cargo-bless
A Cargo subcommand that checks your dependencies against blessed.rs recommendations and suggests modern alternatives.
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)
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) |
--fail-on=LEVELS |
Exit non-zero when matching severity found (e.g., high, medium,high) |
--offline |
Skip crates.io/GitHub fetches, use local cache only |
--workspace |
Analyze all workspace members |
--package=NAME |
Only analyze specific package(s) in a workspace |
--all-targets |
Include dev-dependencies and build-dependencies |
--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.0
๐ 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
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
| Pattern | Suggestion | Kind | Impact |
|---|---|---|---|
lazy_static |
std::sync::LazyLock |
StdReplacement | High |
once_cell |
std::sync::LazyLock / OnceLock |
StdReplacement | High |
memmap |
memmap2 |
Unmaintained | High |
failure |
anyhow + thiserror |
Unmaintained | High |
iron |
axum |
Unmaintained | High |
structopt |
clap v4 (derive) |
ModernAlternative | Medium |
actix-web |
axum |
ModernAlternative | Medium |
log |
tracing |
ModernAlternative | Medium |
chrono |
time |
ModernAlternative | Medium |
env_logger |
tracing-subscriber |
ModernAlternative | Medium |
reqwest + serde_json |
reqwest with json feature |
FeatureOptimization | Low |
tokio + async-std |
tokio only |
ComboWin | Medium |
log + env_logger |
tracing + tracing-subscriber |
ComboWin | Medium |
warp |
axum |
ModernAlternative | Medium |
rocket |
axum |
ModernAlternative | Medium |
maplit |
HashMap::from / BTreeMap::from |
StdReplacement | High |
error-chain |
anyhow + thiserror |
Unmaintained | High |
derivative |
derive_more |
Unmaintained | High |
proc-macro-error |
thiserror |
ModernAlternative | Medium |
anyhow + error-chain |
pick one pattern | ComboWin | Medium |
bytes + try_from_bytes |
bytes native slicing |
FeatureOptimization | Low |
Rules are embedded at compile time from data/suggestions.json. PRs to add more are welcome.
How --fix works
Only some suggestion types are auto-fixable (the ones that only need Cargo.toml changes):
- StdReplacement โ removes the dep (you still need to update your source code)
- Unmaintained โ renames the dep key to the maintained fork
- FeatureOptimization โ removes the extra dep and enables the feature on the main dep
ModernAlternative and ComboWin are reported but not auto-fixed, since they require source code changes.
Code-audit findings are advisory in this release. --fix only edits dependency declarations in Cargo.toml; it never rewrites Rust source files.
Before any edit, --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)octocrabchecks 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.