cargo-bless
A Cargo subcommand that checks your dependencies against blessed.rs recommendations and suggests modern alternatives.
cargo-bless checks whether your Rust dependency tree is modern, boring, and defensible.
What it does
- Scans your
Cargo.tomldependency tree (direct + transitive, with features) - Matches against a built-in rule database sourced from blessed.rs
- Detects single-crate replacements and combo optimizations (e.g. dropping
serde_jsonwhenreqwesthas thejsonfeature) - Runs a built-in bullshit detector code audit for suspicious Rust complexity patterns
- Fetches live metadata from crates.io (latest version, downloads) and GitHub (last push, archived status)
- Optionally applies safe fixes to your
Cargo.tomlwith--fix(preview first with--dry-run)
What cargo-bless is not
- It is not a replacement for
cargo audit,cargo deny, or license/security policy tooling. - It is not automatic truth. Recommendations include confidence, migration risk, autofix safety, and evidence source.
- It is not a source rewriter.
--fixonly applies rules marked as safe Cargo.toml-only edits. - It is not a command to blindly run in production without reading the report.
Installation
From crates.io:
From source:
Usage
CLI Flags
| Flag | Description |
|---|---|
--fix |
Apply auto-fixable suggestions to Cargo.toml |
--dry-run |
Preview changes without writing (use with --fix) |
--audit-code |
Explicitly run the bullshit detector code audit |
--no-audit-code |
Skip the default bullshit detector code audit |
--diff |
With cargo bless bs, audit only changed lines from git diff HEAD |
--verbose |
Show every code-audit finding instead of the top findings summary |
--json |
Output suggestions as JSON array (for CI/pipelines) |
--offline |
Skip crates.io/GitHub fetches, use local cache only |
--policy=PATH |
Use custom bless.toml policy file |
--update-rules |
Fetch latest rules from blessed.rs |
--manifest-path=PATH |
Path to Cargo.toml (defaults to current directory) |
Policy File (bless.toml)
Drop a bless.toml next to your Cargo.toml to customize behavior:
# Ignore specific packages
= ["internal-crate"]
# Per-package overrides
[]
= true
= "We use lazy_static for cross-crate compatibility"
# Global settings
[]
= true
= 10
[]
= ["src/generated", "tests/fixtures"]
= ["UnwrapAbuse"]
Or pass a custom path: cargo bless --policy=custom-bless.toml
Example
$ cargo bless
๐ฅ cargo-bless v0.1.3
๐ Scanning dependencies...
๐ฆ Direct dependencies (16)
โข reqwest 0.12.28 [json, default-tls, ...]
โข serde_json 1.0.149 [default, ...]
...
Found 16 direct deps, 317 total.
๐ Fetching live intelligence...
๐ Modernization report for my-project v0.1.0
โข [LOW] reqwest+serde_json โ reqwest with "json" feature
[HIGH confidence] [LOW risk] [autofix: Cargo.toml-only] evidence: crate docs
reqwest can deserialize JSON directly when its json feature is enabled; cargo-bless only suggests this when serde_json is not used directly in source
latest: v0.13.2, 64.6M recent downloads
0 high-impact upgrades available.
๐งจ Bullshit detector code audit
Scanned 8 Rust files.
๐จ Bullshit detected: 2 findings
unwrap abuse: 1, fake complexity: 1
โข unwrap abuse src/main.rs:14:35
unwrap() is a runtime trap dressed up as confidence.
Fix: Propagate the error with ?, add context, or handle the failure explicitly.
$ cargo bless --fix --dry-run
๐ Dry-run: the following changes would be made:
- serde_json = "1"
Changes that would be applied:
โ Removed `serde_json`, enabled `json` feature on `reqwest`
Built-in rules
Each rule carries trust metadata:
impact: how important the dependency choice may be.confidence: how strong the recommendation is.migration_risk: how likely the change is to require careful review.autofix_safety: whethercargo bless --fixmay editCargo.toml.evidence_source: where the recommendation is grounded.
| Pattern | Suggestion | Impact | Confidence | Risk | Autofix |
|---|---|---|---|---|---|
lazy_static |
std::sync::LazyLock |
High | High | Low | Manual |
once_cell |
std::sync::LazyLock / OnceLock |
High | High | Low | Manual |
memmap |
memmap2 |
High | High | Medium | Manual |
failure |
anyhow + thiserror |
High | High | Medium | Manual |
iron |
axum |
High | High | High | Manual |
structopt |
clap v4 (derive) |
Medium | High | Medium | Manual |
log |
tracing |
Medium | Medium | Medium | Manual |
chrono |
consider time |
Medium | Low | Medium | Manual |
reqwest + serde_json |
reqwest with json feature |
Low | High | Low | Cargo.toml-only |
serde_derive |
serde with derive feature |
Low | High | Low | Cargo.toml-only |
clap + clap_derive |
clap with derive feature |
Low | High | Low | Cargo.toml-only |
Rules are embedded at compile time from data/suggestions.json. PRs to add more are welcome.
How --fix works
Only suggestions marked autofix_safety = "CargoTomlOnly" are auto-fixable.
StdReplacement, Unmaintained, ModernAlternative, and ComboWin are reported but not auto-fixed by default, since they usually require source code changes or architectural judgment.
Code-audit findings are advisory in this release. --fix only edits dependency declarations in Cargo.toml; it never rewrites Rust source files.
Before any write, --fix creates a Cargo.toml.bak backup and runs cargo update afterward.
How it works
cargo_metadataparses the full resolved dependency tree with features- Rules from
data/suggestions.jsonare matched against direct deps (single-crate and combo patterns) crates_io_api::SyncClientfetches live metadata (cached to~/.cache/cargo-bless/with 1-hour TTL)reqwestchecks GitHub forpushed_at,archived, and star count- The bullshit detector scans Rust files under
src,tests,examples, andbenchesfor static complexity patterns toml_editapplies fixes while preserving comments and formatting
Network calls are non-fatal โ if you're offline, the rule-based report still works.
License
MIT -- see LICENSE-MIT.