cfg-rs: A Configuration Library for Rust Applications
cfg-rs is a lightweight, flexible configuration loader for Rust applications. It composes multiple sources (files, env, inline maps, random, etc.), supports live refresh, placeholder expansion, and derive-based typed configs — all without a serde dependency.
See the examples directory for end-to-end demos.
Documentation map
If you are new to this crate, read in this order:
- Quick start in this README
- Examples for end-to-end usage patterns
- docs.rs API reference for type-level details
- CONTRIBUTING.md for contribution and documentation standards
- Examples: https://github.com/leptonyu/cfg-rs/tree/main/examples
- API docs: https://docs.rs/cfg-rs
- Contributing guide: CONTRIBUTING.md
Features
- Single call to load typed config: see Configuration::get
- Derive your config types: see FromConfig
- Default values via field attributes: see field attributes
- Placeholder expansion like
${cfg.key}: see ConfigValue - Random values under the
randfeature (e.g.configuration.get::<u8>("random.u8")) - Refreshable values via RefValue and refreshable Configuration
- Field-level validation via
#[validate(...)]rules (range, length, not_empty, custom, regex) - Pluggable sources with clear priority: see register_source[^priority]
- No serde dependency
[^priority]: Source precedence follows registration order — earlier registrations have higher priority.
Supported formats and feature flags
Built-in file parsers (enable via Cargo features):
| Feature | File extensions | Notes |
|---|---|---|
toml |
.toml, .tml |
Typed values and nested tables |
yaml |
.yaml, .yml |
Friendly for hand-written configs |
json |
.json |
Good for generated or machine-edited config |
ini |
.ini |
Flat/simple legacy formats |
Other useful features:
validate(built-in): supports#[validate(range)],#[validate(length)],#[validate(not_empty)], and#[validate(custom = ...)]rand: random value provider (e.g.random.u8,random.string)log: minimal logging integration for value parsingcoarsetime: coarse time helpers for time-related valuesregex: enables#[validate(regex = ...)]validator
Tip: in application crates, define your own feature aliases (e.g. full-config = ["cfg-rs/full"]) so downstream users can enable capabilities consistently.
Installation
Add to your Cargo.toml with the features you need:
[]
= { = "^1.0", = ["toml"] }
For a batteries-included setup, use the convenience feature set:
= { = "^1.0", = ["full"] }
Example guide
This README organizes examples into two tracks:
- Derive-first typed config (
#[config(...)]+#[validate(...)]) - Source composition (from simple to complex)
1) Derive-first (recommended)
Use derive for app-facing config structs. This single example covers:
#[config(name = "...")]#[config(default = ...)]- Placeholder defaults via
${...}in values #[validate(...)]
let cfg: AppCfg = from_static_map!;
assert_eq!;
assert_eq!;
assert_eq!;
Notes:
- Placeholder expressions are value syntax, not a separate derive attribute.
- Full derive attribute reference: derive.FromConfig
- Validation rules:
range,length,not_empty,custom,regex(feature =regex)
2) Source composition (simple -> complex)
a) Simplest: predefined stack
use *;
let configuration = with_predefined.unwrap;
// let port: u16 = configuration.get("app.port").unwrap();
b) Common: explicit env + file
use *;
let configuration = new
.register_prefix_env.unwrap
.register_file.unwrap;
c) Advanced: layered sources with deterministic priority
use *;
init_cargo_env!;
let mut configuration = new
// Layer 0 (highest): Cargo env source.
.register_source.unwrap
// Layer 1: Inline key-values.
.register_kv
.set
.finish
.unwrap;
// Layer 2: Random values (feature = "rand").
// Layer 3: Environment variables with prefix `APP_`.
configuration = configuration.register_prefix_env.unwrap;
// Layer 4 (lowest): File source.
configuration = configuration.register_file.unwrap;
// Optional: merge inline file content.
See register_kv, register_file, register_random, and register_prefix_env.
Placeholders, randoms, and refresh
- Placeholder expansion: use
${some.key}inside string values; see ConfigValue - Random values: under
rand, keys likerandom.u8,random.stringprovide per-read randoms - Refreshing:
Configuration::refresh()re-reads sources that allow refresh;RefValue<T>updates on refresh
Runnable examples
simple: minimal setup (full feature set)profile: working with profiles (requirestoml)watch: basic file watching and refresh (requiresyaml)refresh: manual refresh andRefValuelogger: logging integration (requiresfull)thread_pool,salak,test_suit: larger samples and integrations
https://github.com/leptonyu/cfg-rs/tree/main/examples
License
MIT © contributors. See LICENSE.
Minimum supported Rust version
This crate supports Rust 1.85 and newer. Older Rust versions are not guaranteed to compile or be tested.
Tips and notes
- Source priority is deterministic: earlier registrations override later ones[^priority]
- This crate intentionally does not depend on serde
- Docs.rs builds enable all features for a comprehensive reference