🎓 A1Learner
🔍
0 of 149 lessons completed

Rust Cargo Features

A feature is a named on/off switch for a piece of a crate, like a setting in an app. A crate with features lets each user build only the needed parts.

Switches live in [features]

You define each switch in Cargo.toml. The special default feature names what is on when the user asks for nothing.

// Cargo.toml
[features]
default = ["shout"]
shout = []
whisper = []

One switch can turn on others

A feature may list other features — and optional libraries, named with dep: in front.

// Cargo.toml
[features]
loud = ["shout", "dep:greet"]

An optional library is a switch too

Mark a dependency optional, and it stays out of the build until someone turns its switch on.

// Cargo.toml
[dependencies]
greet = { path = "../greet", optional = true }

Code reacts with cfg!

cfg! tests a switch while compiling. Code for an off switch is left out of the program.

if cfg!(feature = "shout") {
    println!("HELLO, FEATURES!");
} else {
    println!("hello, features");
}

Choose switches on the command line

Flags turn extra switches on for one build, switch the default set off, or turn everything on at once.

cargo run --features whisper
cargo run --no-default-features
cargo run --all-features

Switches on a library you use

The same words work inside a dependency line. Add default-features = false to the same line to refuse that library's default set.

// Cargo.toml
[dependencies]
serde = { version = "1", features = ["derive"] }

Example

// Cargo.toml
// [features]
// default = ["shout"]
// shout = []
// whisper = []
fn main() {
    if cfg!(feature = "shout") {
        println!("HELLO, FEATURES!");
    } else {
        println!("hello, features");
    }
    if cfg!(feature = "whisper") {
        println!("(whisper mode is on)");
    }
}

Key points

  • Feature: a named on/off switch for a piece of your crate.
  • You define the switches.
  • The person building the crate chooses which are on.
  • Writing dep:greet anywhere in [features] removes that automatic switch.
  • The library can then only be reached through a named feature like loud.
  • Features merge across a project.
  • Two of your libraries may switch on different features of the same third library.
  • Cargo still builds that library once.
  • It builds it with the union of all the features asked for.
  • Name each feature after what it switches on, with no filler words: std, not use-std or with-std.
  • A negative name like no-std is practically never right, because features must only ever add
  • Use cargo run --features whisper to turn extra switches on for one build.
  • Separate several with commas.

In this example, the comment shows the [features] section of Cargo.toml. It defines two switches, shout and whisper, and the default set holds only shout. A plain cargo run therefore builds with shout on and whisper off. The cfg! test finds shout on, so the program prints HELLO, FEATURES! in capitals. The whisper test is false, so the second printed line is left out. Run it with cargo run --features whisper and the extra line appears. Run it with cargo run --no-default-features and the quiet line hello, features prints instead.

Note

A feature may only ever add.

Because Cargo merges everyone's choices into one build, a switch that removed code would break strangers' projects.

Features are additive by design.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

You build the example project with cargo run --no-default-features. What prints?