Cargo and Package Management
Cargo Commands
Cargo commands provide a unified command-line interface for creating, checking, building, testing, benchmarking, documenting, inspecting, and publishing Rust packages. In addition to built-in subcommands, any executable named cargo-<name> on your system PATH can be invoked directly as cargo <name>.
Daily Development Loop:
cargo check ---> cargo clippy ---> cargo test ---> cargo build --release
(Type-check) (Static lints) (Run tests) (Optimized binary)
Core Built-In Cargo Commands
| Category | Command | Short Alias | Description |
|---|---|---|---|
| Scaffolding | cargo new <path> |
— | Creates a new Cargo package in <path> (--lib for a library). |
| Scaffolding | cargo init |
— | Initializes a Cargo package in the current existing directory. |
| Compilation | cargo check |
cargo c |
Type-checks code and dependencies without running LLVM codegen (much faster than build). |
| Compilation | cargo build |
cargo b |
Compiles the package (--release for optimized production builds). |
| Execution | cargo run |
cargo r |
Compiles and executes a binary target (--bin <name> or --example <name>). |
| Verification | cargo test |
cargo t |
Compiles and runs unit, integration, and documentation tests. |
| Verification | cargo bench |
— | Compiles and runs benchmarks. |
| Quality | cargo clippy |
— | Runs the Clippy static analysis linter (--all-targets). |
| Quality | cargo fmt |
— | Formats all Rust source files with rustfmt (--check in CI). |
| Quality | cargo fix |
— | Automatically applies compiler-suggested machine-applicable lint and edition fixes. |
| Dependencies | cargo add / cargo remove |
— | Adds or removes dependencies in Cargo.toml. |
| Dependencies | cargo tree |
— | Prints a visual tree of the resolved dependency graph. |
| Dependencies | cargo update |
— | Updates versions recorded in Cargo.lock. |
| Maintenance | cargo clean |
— | Removes the target/ directory (or specific package artifacts with -p <pkg>). |
| Distribution | cargo doc |
cargo d |
Generates HTML API documentation (--open). |
| Distribution | cargo publish |
— | Packages and uploads a crate to crates.io (--dry-run to test locally). |
| Distribution | cargo install <crate> |
— | Builds and installs a binary crate into ~/.cargo/bin/ (--locked). |
Inspecting the Dependency Graph with cargo tree
cargo tree is built directly into Cargo and helps diagnose why a transitive crate is included, which features are enabled on each crate (-e features), or why two versions of the same crate exist in the graph (--duplicates):
# 1. Show why a specific transitive crate (`syn`) is pulled into the build
cargo tree --invert syn
# 2. List all duplicate crate versions in the dependency graph
cargo tree --duplicates
# 3. Show active feature flags across the dependency graph
cargo tree -e features
my_app v0.1.0 (/Users/dev/my_app)
└── serde v1.0.218
└── serde_derive v1.0.218 (proc-macro)
└── syn v2.0.98
How Custom Subcommands Work (cargo-<name>)
When you run cargo nextest or cargo audit, Cargo searches the directories in your PATH for an executable named cargo-nextest or cargo-audit and invokes it, passing nextest or audit as the first argument (argv[1]):
fn resolve_subcommand_binary(subcommand: &str) -> String {
format!("cargo-{subcommand}{}", std::env::consts::EXE_SUFFIX)
}
fn main() {
println!("Subcommand binary for 'audit': {}", resolve_subcommand_binary("audit"));
}
Subcommand binary for 'audit': cargo-audit