It also covers matching an existing project's Cargo.toml conventions before introducing a competing crate, and the version-verification discipline (never trust a remembered patch number; confirm current versions on crates.io/Context7/Exa).
Out of scope: once a crate is chosen, its detailed API usage belongs to the matching domain skill (rust-web-backend, rust-async-concurrency, rust-error-handling) or direct docs verification (docs.rs/crates.io → Context7 → Exa).
Rust Ecosystem & Crates
Agent Workflow (MANDATORY)
Before ANY crate selection, spawn 3 agents in parallel, one Agent call each with a name:
- fuse-ai-pilot:explore-codebase - Read existing
Cargo.tomlto match established choices - fuse-ai-pilot:research-expert - Confirm the CURRENT version + maintenance status on crates.io via Context7/Exa
- mcp__context7__query-docs - Pull the chosen crate's current API before writing code
After implementation, run fuse-ai-pilot:sniper for validation.
Overview — the decision map
| Domain | De-facto standard (2026) | Reach for it when |
|---|---|---|
| Serialization | serde (+ serde_json) |
Any (de)serialization; derive Serialize/Deserialize |
| CLI parsing | clap (derive API) |
Argument parsing, subcommands, help generation |
| Async runtime | tokio |
Almost all async I/O; the ecosystem default |
| Web framework | axum |
HTTP servers on tokio + tower middleware |
| HTTP client | reqwest |
Outbound HTTP, JSON, TLS |
| Database | sqlx / sea-orm / diesel |
See db-and-async.md for the choice |
| Error (libraries) | thiserror |
Typed error enums in a library's public API |
| Error (apps) | anyhow |
Ergonomic Result with context in binaries |
| Observability | tracing (+ tracing-subscriber) |
Structured, async-aware logs and spans |
Critical Rules
- ALWAYS verify the current version before writing a
Cargo.toml- versions move faster than this skill. Confirm on crates.io or via Context7; never paste a remembered patch number. serde 2.0is NOT stable - it is under discussion. Depend onserde = "1"today; do not write2.0.thiserrorfor libraries,anyhowfor applications - never exposeanyhow::Errorin a library's public API.- One async runtime - standardize on
tokio; mixing runtimes causes executor conflicts. - Match existing choices first - read the project's
Cargo.tomlbefore introducing a competing crate.
Architecture
Cargo.toml
├── [dependencies]
│ ├── serde / serde_json # data
│ ├── tokio (features = [...]) # runtime
│ ├── axum / reqwest # web in/out
│ ├── sqlx | sea-orm | diesel # persistence (pick one)
│ ├── thiserror | anyhow # errors (lib vs app)
│ └── tracing / tracing-subscriber
→ See cargo-toml-stack.md for a complete manifest
Reference Guide
Concepts
| Topic | Reference | When to Consult |
|---|---|---|
| Decision map | crate-decision-map.md | Choosing per domain, error strategy, observability |
| DB & async | db-and-async.md | sqlx vs sea-orm vs diesel, tokio + axum wiring |
Templates
| Template | When to Use |
|---|---|
| cargo-toml-stack.md | Scaffolding a web-service manifest |
Quick Reference
Error handling split
// Library: typed, matchable errors.
#[derive(thiserror::Error, Debug)]
pub enum StoreError {
#[error("not found: {0}")]
NotFound(String),
}
// Application: contextual, any error.
use anyhow::Context;
let cfg = std::fs::read_to_string(path).context("reading config")?;
→ See crate-decision-map.md for the full rationale
Best Practices
DO
- Verify each crate's current version on crates.io before committing it
- Standardize on
tokioand enable only the features you use - Use
thiserrorin libraries,anyhowin binaries - Prefer the crate the project already uses over a "better" alternative
DON'T
- Write
serde = "2"— it is not stable - Hardcode a remembered patch version without checking
- Expose
anyhow::Errorfrom a library API - Mix async runtimes in one binary