Cargo Basics
10 examples to get you started with Cargo - 7 basic and 3 intermediate.
Prerequisites
- Rust 1.97.0 with edition 2024 (
rustup default stable) cargo --versionprints 1.97 or newer
Basic Examples
1. Create a New Binary Crate
cargo new scaffolds a runnable project with Cargo.toml and src/main.rs.
cargo new greeter
cd greeter
cargo run- Creates
Cargo.tomlwith[package]metadata and edition 2024 src/main.rsis the binary entry pointtarget/holds build artifacts (gitignore it)- Default output is a debug build in
target/debug/
Related: Cargo.toml Explained - manifest fields
2. Create a Library Crate
Use --lib when building a reusable crate instead of a binary.
cargo new --lib math_utils
cd math_utilspub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn adds() {
assert_eq!(add(2, 2), 4);
}
}- Library root is
src/lib.rs - Public API is everything marked
pub - Unit tests live in the same file under
#[cfg(test)] - Consumers add
math_utils = "0.1"to theirCargo.toml
Related: Workspaces - multi-crate repos
3. Build and Run
cargo build compiles; cargo run compiles and executes the binary.
cargo build # debug (fast compile)
cargo build --release # optimized
cargo run -- arg1 arg2- Debug builds include symbols for
dbg!and backtraces --releaseuses the[profile.release]settings- Extra args after
--go to your program, not Cargo cargo checktype-checks without linking (fastest feedback loop)
Related: Profiles & Build Settings - opt levels
4. Run Tests
cargo test runs unit tests, integration tests, and doctests.
cargo test
cargo test add_works -- --nocapture
cargo test --doc- Unit tests in
src/**/*.rsunder#[cfg(test)] - Integration tests in
tests/*.rs(separate crates) -- --nocaptureshowsprintln!from tests- Failed tests print a backtrace with
RUST_BACKTRACE=1
Related: Testing Basics - full testing guide
5. Add a Dependency
Declare crates in [dependencies]; Cargo resolves versions and builds a lockfile.
[dependencies]
serde = { version = "1.0", features = ["derive"] }cargo add serde --features derive
cargo buildcargo addeditsCargo.tomland fetches the crateCargo.lockpins exact versions for reproducible builds- Commit
Cargo.lockfor binaries; libraries often omit it cargo update -p serdebumps one crate within semver bounds
Related: Dependency Management - updates and audit
6. Project Layout
A standard binary crate looks like this:
my_app/
├── Cargo.toml
├── Cargo.lock
├── src/
│ └── main.rs
└── tests/
└── integration_test.rs
src/main.rs= binary root;src/lib.rs= library root (one or both)benches/for Criterion benchmarks;examples/for sample binariesbuild.rsruns before compilation when native code or codegen is needed- Module files go under
src/asmod_name.rsormod_name/mod.rs
Related: Build Scripts (build.rs) - custom build steps
7. Inspect the Project
Cargo subcommands help you understand what you are building.
cargo metadata --format-version 1 | jq '.packages[].name'
cargo tree -p my_app
cargo doc --opencargo treeshows the dependency graphcargo doc --openbuilds and opens API docs for dependenciescargo metadatais the machine-readable project graph- Use these before adding heavy transitive dependencies
Related: Useful Cargo Subcommands - expand, bloat, watch
Intermediate Examples
8. Features and Conditional Compilation
Enable optional functionality with Cargo features.
[features]
default = ["std"]
std = []
[dependencies]
log = { version = "0.4", optional = true }#[cfg(feature = "std")]
pub fn init() {
log::info!("initialized");
}cargo build --no-default-features
cargo build --features std- Features are the primary way to trim compile time and binary size
#[cfg(feature = "...")]gates code at compile time- Default features should be the common case
- Document feature flags in crate README and
Cargo.tomlcomments
Related: Features & Optional Dependencies
9. Workspace Commands
Run Cargo at the workspace root to build every member crate.
cargo build --workspace
cargo test -p api
cargo run -p cli -- --help-pselects one package in a workspace--workspacebuilds all members sharing oneCargo.lock- Shared
[workspace.dependencies]deduplicate version pins - CI usually runs
cargo test --workspace --all-features
Related: Workspaces - boundaries and layout
10. Publish to crates.io
Prepare metadata, verify locally, then publish.
cargo publish --dry-run
cargo package
cargo publish[package]
name = "my_crate"
version = "0.1.0"
edition = "2024"
license = "MIT OR Apache-2.0"
description = "One-line summary for crates.io"
repository = "https://github.com/org/my_crate"cargo publish --dry-runcatches manifest errors early- Semver: breaking API changes require a major bump
cargo packageproduces the.cratetarball locally- Set
CARGO_REGISTRY_TOKENfor non-interactive CI publish
Related: Publishing to crates.io
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.