Cargo and Package Management
Workspaces
A Cargo workspace groups multiple related packages into a single repository that shares one unified Cargo.lock file and one shared target/ build directory. Because all workspace members share target/ and Cargo.lock, common dependencies (such as serde, tokio, or syn) are resolved to a single consistent version and compiled only once across the entire workspace.
my_workspace/
├── Cargo.toml <-- Virtual Workspace Manifest (`[workspace]`)
├── Cargo.lock <-- Single shared lockfile for all members!
├── target/ <-- Single shared build cache for all members!
└── crates/
├── core_types/
│ ├── Cargo.toml <-- Member 1: `core_types` (library)
│ └── src/lib.rs
├── storage_engine/
│ ├── Cargo.toml <-- Member 2: `storage_engine` (depends on `core_types`)
│ └── src/lib.rs
└── cli_server/
├── Cargo.toml <-- Member 3: `cli_server` (binary)
└── src/main.rs
Workspace Inheritance (workspace = true)
Modern Cargo workspaces define shared package metadata (version, edition, license, rust-version), dependency versions ([workspace.dependencies]), and lint rules ([workspace.lints]) once in the root Cargo.toml. Individual member crates inherit those settings with .workspace = true, eliminating version drift across dozens of crates:
1. Root Workspace Cargo.toml
[workspace]
resolver = "3"
members = [
"crates/core_types",
"crates/storage_engine",
"crates/cli_server",
]
[workspace.package]
version = "0.4.0"
edition = "2024"
rust-version = "1.85"
license = "MIT OR Apache-2.0"
repository = "https://github.com/example/my_workspace"
[workspace.dependencies]
# External dependencies shared across workspace members
serde = { version = "1.0", features = ["derive"] }
# Internal workspace member paths
core_types = { path = "crates/core_types", version = "0.4.0" }
storage_engine = { path = "crates/storage_engine", version = "0.4.0" }
[workspace.lints.rust]
unsafe_code = "forbid"
2. Member Crate crates/storage_engine/Cargo.toml
[package]
name = "storage_engine"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
[dependencies]
core_types.workspace = true
serde.workspace = true
[lints]
workspace = true
Workspace-Scoped Cargo Commands
| Command | Behavior |
|---|---|
cargo build --workspace |
Compiles all member packages in the workspace. |
cargo test --workspace |
Runs unit, integration, and doc tests across all workspace members. |
cargo test -p storage_engine |
Runs tests only for the storage_engine member package (-p / --package). |
cargo run -p cli_server |
Runs the binary in the cli_server member package from any directory in the workspace. |
cargo check --workspace --all-targets |
Type-checks every library, binary, example, and test across the entire workspace. |
// Simulating `core_types` and `storage_engine` interacting in a workspace:
pub mod core_types {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RecordId(pub u64);
}
pub mod storage_engine {
use super::core_types::RecordId;
pub fn format_key(id: RecordId) -> String {
format!("rec:{:08x}", id.0)
}
}
fn main() {
let id = core_types::RecordId(255);
println!("Workspace key: {}", storage_engine::format_key(id));
}
Workspace key: rec:000000ff