18 / 20 · Day 7
Day 7 · Concept 18

Cargo & crates

One tool runs the entire workflow: build, test, doc, publish, format, lint. crates.io is the central registry. Cargo.toml declares dependencies; Cargo.lock pins exact versions.


1 · The commands you'll use daily

CommandWhat it does
cargo new myappScaffold a new binary project (use --lib for library).
cargo runBuild (if needed) and run the binary.
cargo build [--release]Build. --release optimises; default is fast-compile debug.
cargo testRun all tests, including doc tests.
cargo checkType-check only. Faster than full build.
cargo doc --openBuild HTML docs and open them.
cargo fmtFormat the whole tree to canonical style.
cargo clippyThe lint pass. Often catches subtle issues.
cargo add serdeAdd a dependency to Cargo.toml.
cargo updateRefresh Cargo.lock within the version ranges in Cargo.toml.

2 · Cargo.toml — the manifest

toml Cargo.toml
[package]
name    = "myapp"
version = "0.1.0"
edition = "2021"

[dependencies]
serde      = { version = "1", features = ["derive"] }
tokio      = { version = "1", features = ["full"] }
reqwest    = "0.12"
anyhow     = "1"
thiserror  = "1"

[dev-dependencies]
proptest = "1"

Semver caret. "1" means "anything 1.x.y but not 2.0". For exact pins, use "=1.2.3". Cargo.lock stores the resolved versions and should be checked in for binaries, ignored for libraries.

3 · Workspaces — many crates, one repo

toml Cargo.toml (workspace root)
[workspace]
members = ["api", "core", "cli"]
resolver = "2"

[workspace.dependencies]
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }

Shared target/, shared lockfile. Inside each sub-crate, depend on workspace deps with serde = { workspace = true }.

4 · Crates worth knowing

CrateFor
serde + serde_jsonJSON, YAML, etc. The serialization standard.
tokioAsync runtime. The default choice.
reqwestHTTP client.
axum / actix-webHTTP servers.
clapCLI argument parsing.
anyhow + thiserrorErrors. Pair them.
tracingStructured logging and spans.
sqlx / dieselDatabase access.
rayonEasy data parallelism — replace .iter() with .par_iter().

5 · Common mistakes

  • Forgetting feature flags. Many crates ship with minimal features by default — tokio needs features = ["full"] for the macros.
  • Running cargo build when you meant --release. Debug builds are easily 10× slower at runtime.
  • Committing target/. It's huge. Make sure it's in .gitignore (cargo new does this).
  • Ignoring clippy. It catches real bugs, not just style.

6 · When it clicks

  • cargo check is your inner loop, not cargo run.
  • You add a crate with cargo add foo without thinking about it.
  • cargo clippy runs in CI on every PR.
Found this useful?