Essential Crates Best Practices
A condensed summary of dependency habits that keep Rust codebases fast to build, safe to upgrade, and easy to onboard.
Search across all documentation pages
A condensed summary of dependency habits that keep Rust codebases fast to build, safe to upgrade, and easy to onboard.
Default to serde + one format crate: serde at boundaries; add serde_json or toml only where needed. Avoid serde_json::Value in domain cores.
Standardize on Tokio for async IO: Mixing runtimes multiplies bugs. Bridge legacy log with tracing-log.
Split errors by crate role: thiserror in libraries, anyhow in binaries. Never leak anyhow::Error from published crates.
Reuse HTTP and DB clients: One reqwest::Client and one sqlx::PgPool per process via LazyLock or Axum state.
Pick chrono or time, not both: Document the choice in workspace README and enforce in review.
Use clap derive for user-facing CLIs: Stable flag names; add aliases before removing old flags.
Reach for rayon only past thresholds: Parallelism has overhead; benchmark small inputs first.
Prefer LazyLock over custom static mut: On Rust 1.80+, std lazy statics reduce once_cell surface.
DashMap is a cache, not a database: Add eviction and persist authoritative state elsewhere.
Enable rustls TLS features by default: OpenSSL only when platform or compliance requires it.
Run cargo deny check in CI: License, advisory, and duplicate version gates catch supply-chain risk early.
Read docs.rs examples before adopting: Crates with runnable examples age better than README-only projects.
Minimize feature flags on heavy crates: tokio = { features = ["rt-multi-thread", "macros", "time"] } beats full when size matters.
Keep workspace dependency versions unified: [workspace.dependencies] in root Cargo.toml prevents version splits.
Commit Cargo.lock for binaries: Libraries may omit; applications and deployable services must lock.
Record MSRV in Cargo.toml: rust-version = "1.97" sets contributor expectations.
Avoid pre-1.0 crates in core paths without pin: 0.x semver allows breaking changes; fork risk assessment required.
Wrap external types in newtypes: Domain modules should not re-export vendor error types blindly.
Schedule quarterly dependency hygiene: cargo update, cargo outdated, and a focused PR fixing advisories.
Cross-link skills and deep sections: Essential crate pages are indexes; authoritative detail lives in topic sections.
Count matters less than depth and maintenance. Ten focused crates beat one unmaintained mega-crate.
When upstream is abandoned and crate is security-critical. Document fork policy in ADR.
Only temporarily with ticket to publish or return to crates.io version.
Add when dataframe analytics are core. Do not pull Polars for simple CSV parsing.
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+.
Reviewed by Chris St. John·Last updated Jul 19, 2026