Rust Cargo Workspaces
A workspace is a group of crates managed together under one top-level Cargo.toml. It allows shared dependency resolution, unified builds/tests, and centralized configuration.
Declaration
Top-level Cargo.toml
:
[workspace]
resolver = "2" # use new feature resolver (optional)
members = ["crate_a", "crate_b", "examples/*"]
exclude = ["old_crate"]
[workspace.dependencies] # optional
serde = "1" # shared dependency for all members
resolver
β "1" (default) or "2" (new, more flexible, better for dependency resolution).members
β list of crate paths included in the workspace. Can use globs (examples/*
).exclude
β paths to ignore (e.g., archived crates).[workspace.dependencies]
β dependencies shared by all members.- Members can override locally or use
workspace = true
to inherit.
- Members can override locally or use
Member Crates
crate_a/Cargo.toml
example:
[package]
name = "crate_a"
version = "0.1.0"
[dependencies]
serde = { workspace = true } # pulls version from workspace
tokio = { version = "1", optional = true } # local override
crate_b = { path = "../crate_b" } # inter-crate dependency
Notes:
workspace = true
β ensures all crates use the same version from[workspace.dependencies]
.- Inter-crate path dependencies are local and versioned independently from crates.io.
- Optional features can still be enabled per member.
Common Workspace Features & Gotchas
Profiles (
[profile.dev]
,[profile.release]
)
* Can be defined globally under `[workspace]`.
* Member crates inherit unless overridden.
Shared Lints / Metadata
Publishing
- Each member crate is published separately unless marked
publish = false
. - Workspace crate cannot be published itself; only members.
Examples / Tests / Benches
- Members can have their own
examples/
,tests/
,benches/
. - Workspace allows
cargo test --all
orcargo build --all
.
Dev-dependencies in Workspace
- Dev-dependencies are not shared by default.
[workspace.dev-dependencies]
can be declared to avoid repeating them in each member.
Features Across Workspace
- Each crate manages its own features.
- Can βforwardβ dependency features using
dep:crate
orcrate/feature
. cargo build --all-features
β enables all features in all workspace members.
Overriding Dependencies
- Overrides a crate globally for all workspace members.
Commands
cargo build
β builds current cratecargo build -p crate_a
β builds specific membercargo build --all
β builds all workspace memberscargo test --all
β runs all tests across workspacecargo check --workspace
β checks all members without buildingcargo update -p crate_name
β update a dependency for all members
Real-world Notes
- Large OSS projects use workspaces to avoid multiple lockfiles and keep dependencies consistent.
- Optional features and dev-dependencies often vary per crate; shared dependencies minimize version conflicts.
- Beware of cyclic dependencies β Cargo forbids them even inside a workspace.
- Path dependencies are local and always take precedence over crates.io.