Configuration & Feature Design
Separate compile-time Cargo features from runtime configuration. Load settings once at startup with validation; gate optional integrations with features.
Recipe
[features]
default = ["metrics"]
metrics = ["dep:prometheus"]#[derive(serde::Deserialize)]
struct Settings {
database_url: String,
port: u16,
}When to reach for this: Multi-environment deploys and optional compile-time backends.
Working Example
let settings = Settings::parse()?; // env + defaults
let pool = PgPoolOptions::new().connect(&settings.database_url).await?;
#[cfg(feature = "metrics")]
prometheus::init();Settingsvalidates port range inparse()- Secrets from env in prod,
.envlocal only - Feature
metricstrims deps in minimal builds
Deep Dive
config crate layers files: config/default.toml + config/production.toml + env overrides. Document each env var in README.
Gotchas
- Runtime feature flags as Cargo features - requires rebuild. Fix: runtime config for ops toggles.
- Secrets in default.toml - leak risk. Fix: env-only secrets.
- feature explosion - matrix CI pain. Fix: group features
full,minimal. - Partial settings clone - stale config. Fix:
Arc<Settings>reload policy documented. - no validation - prod boot with port 0. Fix:
deny_unknown_fields+ validate fn.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| figment | layered sources | tiny CLI |
| clap env | CLI+server hybrid | many nested settings |
FAQs
reload config?
SIGHUP reload for non-secret fields; secrets need restart.
12-factor?
All config in env; files for local dev only.
test config?
Settings::test() with dummy URLs in tests module.
clap merge?
Flatten CLI overrides onto Settings for admin tools.
feature docs?
README matrix: feature -> deps -> use case.
wasm config?
Embed config at compile or JS injection at runtime.
k8s configmap?
Mount files read by config crate path.
preview env?
Separate namespace + settings prefix per env.
audit settings?
Log non-secret effective config at startup (redacted).
breaking settings rename?
Support old env alias one release with deprecation log.
Related
- Features & Optional Dependencies
- Configuration and Env
- Architecture Decision Checklist
- Deployment Basics
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+.