cargo-bless
A Cargo subcommand that checks your dependencies against blessed.rs recommendations and suggests modern alternatives.
On crates.io: cargo-bless · Generated API docs: docs.rs/cargo-bless · Changelog: changelog.md · Repo docs: docs/
cargo-bless checks whether your Rust dependency tree is modern, boring, and defensible.
Release framing (semver)
| Version | What it represented |
|---|---|
| 0.1.0 | Birth |
| 0.1.1–0.1.3 | Rapid hardening |
| 0.1.4 | First “people might actually try this” slice — think how does a stranger feel after running this once? |
| 0.1.5 | Stranger-trust polish shipped: cargo bless --feedback, softer chrono ↔ time copy, root changelog |
| 0.1.6 | Documentation pass: README links, docs/ index (architecture, CLI, contributing) |
| 0.1.7 | Rule merges fixed (embedded suggestions win over blessed cache/tooling); curated rules + selective blessed rows (ggez); CI smoke for --feedback |
Likely near-term forks:
- 0.1.x — Residual polish: optional
--summary, even safer--fixwording, example “stress test” output in docs. - 0.2.0 — Policy / config maturity: fuller
bless.tomlsemantics, fail-on gates, workspace handling, cache-first behavior (see phase 3 design).
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) - Optionally 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 |
Include the bullshit detector code audit in the main report |
--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) |
--feedback |
Emit version, dep counts, suggestion counts, and top code-audit hotspots (paste into issues; no telemetry) |
Pasteable feedback (--feedback)
Tried cargo-bless on a non-trivial tree? Paste the output of cargo bless --feedback into a GitHub issue. It prints aggregate counts plus coarsely-ranked source locations (path::fn where we can infer a function from the finding line); it does not list crate names from your dependency graph or cargo-bless’s suggestion text. No network: this mode skips live intel; it still runs the full local code audit. --manifest-path and --policy apply the same as a normal run.
Example shape:
cargo-bless feedback block
version: 0.1.7
direct_deps: 46
total_deps: 624
suggestions: 2
high_impact: 1
code_audit_findings: 401
top_hotspots:
- src/main.rs::run_simulation
- src/main.rs:apply_forces
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 --audit-code
🔥 cargo-bless v0.1.7
📋 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- With
--audit-codeorcargo bless bs, the bullshit detector scans Rust files undersrc,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.
Extended documentation
These files also live under docs/ in the repository (links work from GitHub and crates.io):
- Documentation index —
docs/README.md - Architecture — module map and pipeline
- CLI reference — flags and subcommands
- Contributing — build, test, release checklist
License
MIT -- see LICENSE-MIT.