/flags/cargo/cargo-build-no-default-features
cargo build --no-default-features: build without the default feature set
- tool
- Cargo
- command
- cargo build
- flag
- --no-default-features, --features LIST, --all-features
- default
- the features listed under default in [features] are enabled
cargo build --no-default-features builds the selected packages without the features listed under default in their [features] table. Combine it with --features a,b to build an exact subset, for example a minimal or no_std configuration, or to check in CI that the crate still compiles without its optional parts. The same flags work for cargo run, cargo test, cargo check and cargo doc.
Effect on cfg(feature)
The crate has a color feature that is on by default:
cargo new -q --vcs none app && cd app
cat >> Cargo.toml <<'EOF'
[features]
default = ["color"]
color = []
json = []
EOF
cat > src/main.rs <<'EOF'
fn main() {
println!("color: {}, json: {}", cfg!(feature = "color"), cfg!(feature = "json"));
}
EOF
echo "--- default"
cargo run -q
echo "--- --no-default-features"
cargo run -q --no-default-features
echo "--- --no-default-features --features json"
cargo run -q --no-default-features --features json
echo "--- --all-features"
cargo run -q --all-featuresOutput
--- default color: true, json: false --- --no-default-features color: false, json: false --- --no-default-features --features json color: false, json: true --- --all-features color: true, json: true
Code behind #[cfg(feature = "color")] is compiled only when the feature is active, so each run produces a different binary.
Feature flags
| Flag | Active features |
|---|---|
| (none) | The default list |
| --no-default-features | None, except those enabled by other crates in the build |
| --features a,b (or -F a,b) | The defaults plus a and b |
| --no-default-features --features a | Only a and what a enables |
| --all-features | Every feature of the selected packages |
| --features dep/feat | Enable feat of the dependency dep |
| -p crate --features x | In a workspace, features of the selected package |
For dependencies: default-features = false
The command-line flag does not reach dependencies. Turn off a dependency's defaults in Cargo.toml:
[dependencies]
serde_json = { version = "1", default-features = false, features = ["alloc"] }cargo add serde_json --no-default-features --features alloc writes the same entry; see cargo add with features.
Pitfalls
- Feature unification. Features are additive across the whole dependency graph. If another crate depends on
serde_jsonwith defaults,default-features = falsein your entry has no effect. Inspect it withcargo tree -e features -i serde_json. - Untested combinations. A crate that only ever builds with defaults often breaks with
--no-default-features. Add a CI job that runscargo check --no-default-features(tools such as cargo-hack test every combination). - Workspaces. In a workspace with resolver 2 or later, the flags apply to the packages selected with
-por the current directory, not to every member. - A misspelled feature name fails the build with
the package 'app' does not contain this feature, so typos do not pass silently.
Release builds are orthogonal to features: cargo build --release changes the optimisation profile, not the feature set.
FAQ
How do I disable default features of a dependency?
The command-line flag only affects the packages you build. For a dependency, write default-features = false in its Cargo.toml entry (or cargo add NAME --no-default-features) and list the features you need with features = [...].
Why is a default feature still enabled after --no-default-features?
Features are unified: if any other crate in the build depends on the same crate without default-features = false, the defaults come back. cargo tree -e features shows which dependency turns them on.
Can I combine --no-default-features with --features?
Yes, that is the usual way to build a minimal configuration: cargo build --no-default-features --features json. Only the listed features (and what they enable) are active.