Cargo is Rust’s official package manager and build tool. It handles compiling your code, managing dependencies, running tests, generating docs, formatting code, and more. Learning a few advanced Cargo commands and features can make your development process smoother and more efficient.
When I began working on larger Rust projects, I realized how powerful Cargo really is. Beyond just building and testing, it helped me catch mistakes early with clippy, keep code readable with fmt, and understand dependencies and performance. Once I learned a few tips and hidden commands, my workflow became faster and more productive.
This article shares some of the most useful Cargo tricks, whether you are debugging, testing, documenting, or preparing a release.
Build Profiles: Debug vs Release
Rust has two build modes:
- Debug is the default (fast to compile, slower runtime)
- Release is optimized (slower to compile, faster runtime)
Run in debug mode (default):
cargo run
Run in release mode:
cargo build --release
This creates an optimized binary in target/release/ instead of target/debug/.
Use release mode when benchmarking or deploying a final build.
Use cargo fmt for Auto Formatting
Rust has an official code formatter: rustfmt.
Install if needed:
rustup component add rustfmt
Then format your whole project:
cargo fmt
This enforces consistent style across your codebase. It is especially useful in teams or open source projects.
Use cargo clippy for Linting
Clippy catches common mistakes and suggests improvements.
Install:
rustup component add clippy
Run:
cargo clippy
Clippy points out:
- Redundant code
- Unused variables
- Style issues
- Possible panics
Fixing these early avoids subtle bugs.
Build Documentation with cargo doc
Rust makes it easy to generate HTML documentation from your code.
Run:
cargo doc --open
This builds docs for your crate and dependencies and opens it in your browser.
Use doc comments like this in your code:
/// Returns the square of a number.
pub fn square(x: i32) -> i32 {
x * x
}
Well-written docs help both others and your future self.
Run Individual Tests
Run all tests:
cargo test
Run tests matching a name:
cargo test add
Run a single file’s integration tests:
cargo test --test file_name
Run only ignored tests:
cargo test -- --ignored
This is helpful for debugging long or slow-running tests.
Check for Compilation Without Building
Use this to quickly verify code compiles:
cargo check
It is faster than cargo build because it skips the final binary generation.
This is perfect during early development.
Use cargo tree to View Dependencies
Install the cargo-tree subcommand:
cargo install cargo-tree
Then run:
cargo tree
This shows your crate’s dependency graph, which helps debug version conflicts or reduce bloat.
Override Dependencies Temporarily
In Cargo.toml, you can override dependencies for testing or debugging:
[dependencies]
serde = "1.0"
[patch.crates-io]
serde = { path = "../serde" }
This is useful when editing a local crate or testing custom versions.
Clean Build Files
Free up space by removing build artifacts:
cargo clean
This deletes the target/ folder.
Useful if switching branches or fixing corrupted builds.
Run Binary Examples
If you have examples/:
examples/
└── demo.rs
Run with:
cargo run --example demo
Examples are great for quick experiments or documentation samples.
Summary
Cargo is more than just a build tool. With commands like clippy, fmt, check, and doc, you can improve code quality, catch bugs early, and speed up development. Learning how to switch between debug and release builds, run specific tests, and explore dependencies will save you time and make your Rust workflow feel effortless.
Rust Intermediate Concepts
- Generic Types in Functions and Structs
- Implementing Traits for Custom Behavior in Rust
- Trait Bounds and Constraints in Rust
- Lifetimes in Rust
- Using Closures (Anonymous Functions) in Rust
- The Iterator Trait and .next() in Rust
- Higher Order Iterator Methods: map, filter, and fold in Rust
- Using impl Trait for Simplicity in Rust
- Advanced Collections: HashSet and BTreeMap in Rust
- Custom Error Types and the Error Trait in Rust
- Option and Result Combinators in Rust
- Writing Unit Tests in Rust
- Integration Testing in Rust
- Logging in Rust with the log Crate
- Cargo Tips and Tricks for Rust Projects
- CLI Argument Parsing with Clap in Rust
- File I/O and File System Operations in Rust
- Running External Commands in Rust
- Make HTTP Requests in Rust with Reqwest
- JSON Serialization and Deserialization in Rust with Serde
- Building a Weather CLI in Rust
- Date and Time Handling in Rust with Chrono
- Using Regular Expressions in Rust with the regex Crate
- Memory Management in Rust
- Understanding Borrow Checker Errors in Rust
- Interacting with Databases in Rust
- Building a Todo List CLI in Rust with SQLite
- Concurrency in Rust