A Cargo subcommand that checks your dependency tree against blessed.rs recommendations and suggests modern, boring, defensible alternatives.
Lead / maintainer: Jason Van Pham (Ruffian-L) β product direction, design, shipping.
Built with collaborators where they earned it; this is a tool, not a model-consciousness project.
| Strength | Where |
|---|---|
| Shipped on crates.io | cargo-bless Β· docs.rs |
| Clear job | lockfile + rules β TTY / JSON / SARIF report |
| Safe defaults | dry-run / diff paths; guarded Cargo.toml fixes |
| Optional intel | crates.io / GitHub / OSV β off until you ask |
| Static audit | --audit-code source scan |
| What it is not | Not βAI rewrote your crate.β Not a replacement for cargo audit alone. |
Built on top of work by many others in the Rust ecosystem (blessed.rs paths, cargo metadata, β¦).
Updated 07/06/2026: attributions Β· 2026-07-25: public-face table
Powered by blessed.rs curated paths Β· optional crates.io + GitHub intel Β· optional Cargo.tomlβonly autofix
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.
flowchart LR
A["Cargo.toml + lock"] --> B["cargo metadata\nresolved features"]
B --> C["Built-in rules\n50 patterns"]
C --> D["Suggestions\n+ trust metadata"]
D --> E["TTY report or JSON"]
E --> F{{"Extras"}}
F --> G["Live intel\ncrates.io / GitHub\nosv.dev advisories"]
F --> H["--fix\nCargo.toml only"]
F --> I["--audit-code\nsrc/ static scan"]
flowchart TD
Start([You are here]) --> Q{Need machine output?}
Q -->|yes| J["cargo bless --json\n(+ --fail-on=β¦ in CI)"]
Q -->|no| R{Paste into GitHub issue?}
R -->|yes| F["cargo bless --feedback\n(root crate)"]
R -->|no| S{Want a one-screen roll-up?}
S -->|yes| Sm["cargo bless --summary"]
S -->|no| D["cargo bless\n(default full report)"]
| 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.7β0.1.8 | Rule merges, blessed.rs ingest, HTML-stripped notes |
| 0.2.0 | --workspace, --summary, --fail-on, JSON per-package, virtual-workspace-safe |
| 0.2.1β0.2.3 | --all-targets, bs --sarif, bs --fail-on-confidence, --init-ci, policy gates |
| 0.2.4β0.2.6 | +17 rules (50 total), --explain, --init-hooks, bs --fix, bs --diff |
| 0.2.7 | New detectors (BoolComparison, StringAntiPattern, DiscardedError, LossyUtf8), 5 more rules, bs --fix --dry-run |
| 0.3.0 | Security advisories via osv.dev, advisory data in JSON output, --no-advisories |
| 0.3.1 | False-positive elimination: #[test] / #[cfg(test)] blocks masked via tree-sitter; default scan scope narrowed to src/ (use --include-tests to opt in); non-src/ crate layouts now scanned correctly |
| 0.4.0 | Maintenance: MSRV 1.80 β 1.85 (edition2024 needed to resolve modern dep graphs), blessed.rs rule-update pipeline repaired, RUSTSEC advisories cleared, Node 20 CI deprecation fixed, Code of Conduct added |
| 0.4.1 | OSV checks now include exact resolved dependency versions, eliminating historical-advisory false positives |
- Scans your
Cargo.tomldependency tree (direct + transitive, with features) - Matches against 50 built-in rules sourced from blessed.rs β single-crate and combo patterns
- Fetches live metadata from crates.io (latest version, downloads), GitHub (last push, archived status), and osv.dev (security advisories)
- Runs a bullshit detector code audit:
UnwrapAbuse,FakeComplexity,TodoUnimplemented,RefCellAbuse,ArcAbuse,BoolComparison,StringAntiPattern,DiscardedError,LossyUtf8, and more - Applies safe fixes to your
Cargo.tomlwith--fix(preview first with--dry-run); auto-replaces.unwrap()β.expect("TODO")withcargo bless bs --fix - Generates CI workflows (
--init-ci) and pre-commit hooks (--init-hooks)
- 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.
From crates.io:
cargo install cargo-blessFrom source:
git clone https://github.com/Ruffian-L/cargo-bless
cd cargo-bless
cargo install --path .cd /path/to/your/crate
cargo bless --offline # no network: rules + local cache only β good βwhat is this?β probe
cargo bless --summary --offline # shortest story: counts + pattern bullets
cargo bless --feedback # issue template: stats + code-audit hotspots (no dep names listed)If the report looks sane, drop --offline to light up crates.io / GitHub intel on the colorful default run.
cargo bless # scan and report (root package)
cargo bless --workspace # every workspace member (virtual workspace manifests OK)
cargo bless --package=foo,bar # only listed member packages (comma-separated)
cargo bless bs # run only the bullshit detector code audit
cargo bless bs --diff # audit only lines changed since HEAD
cargo bless bs --fix # auto-replace .unwrap() β .expect("TODO") (writes *.rs.bak backups)
cargo bless bs --fix --dry-run # preview what bs --fix would change (no writes)
cargo bless bs --include-tests # also scan tests/, examples/, benches/ (default: src/ only)
cargo bless --feedback # paste-safe issue block (counts + code-audit hotspots; root crate only)
cargo bless --summary # paste-friendly dependency roll-up (counts + patterns; no live intel fetch)
cargo bless --fail-on=high # exit non-zero if any suggestion matches listed impact(s)
cargo bless --fix --dry-run # preview Cargo.toml diff only (no writes)
cargo bless --fix # apply Cargo.toml autofixes (`*.toml.bak`; never touches `.rs`)
cargo bless --update-rules # fetch latest rules from blessed.rs
cargo bless --json # structured JSON (`packages`, optional `code_audit`, `security_advisories`)
cargo bless --offline # skip crates.io/GitHub/osv.dev intel; rules + cache still apply
cargo bless --no-advisories # skip osv.dev advisory check even when online
cargo bless --audit-code # include code audit in the main dependency run
cargo bless --explain lazy_static # show full details for a rule (kind, confidence, risk, reason)
cargo bless --init-ci # write .github/workflows/bless.yml and exit
cargo bless --init-hooks # write .git/hooks/pre-commit and exitflowchart TB
W["Workspace Cargo.toml<br/>[workspace] members"]
W --> P1["crates/foo"]
W --> P2["crates/bar"]
subgraph scan ["One cargo metadata resolve"]
P1 --> R["Per-member suggestions"]
P2 --> R
R --> F["Optional --fix per Cargo.toml"]
end
$ cargo bless --workspace --offline
π cargo-bless v0.4.1
π Scanning dependenciesβ¦
β’ api v0.3.0 β 11 direct, 189 total (crates/api/Cargo.toml)
β’ worker v0.1.0 β 6 direct, 155 total (crates/worker/Cargo.toml)
Workspace: 2 members Β· 17 direct deps (sum) Β· 344 resolved rows (sum).
π¦ api v0.3.0 (crates/api/Cargo.toml)
β’ [HIGH] lazy_static β std::sync::LazyLock
β¦
π¦ worker v0.1.0 (crates/worker/Cargo.toml)
β’ [MED] log β tracing
β¦
| Flag | Description |
|---|---|
--fix |
Apply Cargo.toml-only autofixes (*.toml.bak on write); never edits Rust sources |
--dry-run |
With --fix, prints the unified diff/plan β no files written, no cargo update |
--audit-code |
Bullshit detector pass merged across selected packages (sums files + alerts) |
--verbose |
Show every code-audit finding instead of the trimmed summary |
--json |
Machine JSON (cargo_bless_version, workspace_scan, packages[], code_audit, security_advisories) |
--offline |
Skip crates.io/GitHub/osv.dev intel; rules + embedded data still apply |
--no-advisories |
Skip the osv.dev advisory check even when online |
--policy=PATH |
Use custom bless.toml policy file |
--update-rules |
Fetch latest blessed-derived rules into the cache |
--manifest-path=PATH |
Workspace or package Cargo.toml (defaults to current directory) |
--feedback |
Issue/discord block: aggregates + hotspots; root crate only (no --workspace/--package) |
--summary |
Short dep summary + pattern bullets; skips live intel; mutually exclusive with --json/--fix/--feedback/--audit-code |
--fail-on=l,m,h,c |
Fail CI when any suggestionβs impact matches (comma-separated; critical aliases high for deps today) |
--workspace |
Analyze all [workspace].members with one cargo metadata call |
--package=NAMES |
Member filter (comma-separated names) |
--all-targets |
Include [dev-dependencies] and [build-dependencies] in analysis |
--explain=PATTERN |
Show full details for a rule β kind, confidence, migration risk, reason, source |
--init-ci |
Write a starter .github/workflows/bless.yml and exit |
--init-hooks |
Write .git/hooks/pre-commit (runs cargo bless bs --fail-on-confidence 0.8) and exit |
| Flag | Description |
|---|---|
--fix |
Auto-replace .unwrap() β .expect("TODO: handle this") (writes *.rs.bak backups) |
--dry-run |
With --fix, preview what would change without writing files |
--diff |
Audit only changed lines from git diff HEAD |
--include-tests |
Also scan tests/, examples/, benches/ (default: src/ only) |
--hardcoded |
Also scan for magic numbers, API keys, IPs, URLs, credentials |
--sarif |
Output findings as SARIF 2.1.0 JSON (for GitHub code scanning / PR annotations) |
--fail-on-confidence=FLOAT |
Exit non-zero if any finding has confidence β₯ this value (0.0β1.0) |
--verbose |
Show every finding instead of the concise summary |
--json |
Machine JSON output |
--manifest-path=PATH |
Path to the Cargo.toml whose source tree should be audited |
--policy=PATH |
Use custom bless.toml for code-audit suppressions |
| Mode | Best for |
|---|---|
Default cargo bless |
Full dependency report + optional crates.io/GitHub intel |
--feedback |
GitHub issues / Discord β aggregates + code-audit hotspots (root crate only) |
--summary |
Quick roll-up β counts + deduped βcrate β suggestionβ lines without fetching live intel |
--json |
CI / automation β stable JSON with packages[].dependency_suggestions and nullable code_audit |
--feedback, --summary, and --json are mutually exclusive. --feedback also rejects --workspace / --package.
Tried cargo-bless on a non-trivial tree? Paste cargo bless --feedback into an issue. It prints aggregate counts plus coarsely-ranked source locations (path::fn); it does not print your dependency crate list or full suggestion text. No network (skips live intel); still runs the local code audit. --manifest-path and --policy work as usual.
Example shape:
cargo-bless feedback block
version: 0.4.1
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
Drop a bless.toml next to your Cargo.toml to customize behavior:
# Ignore specific packages
ignore_packages = ["internal-crate"]
# Per-package overrides
[packages.lazy_static]
suppress = true
keep_reason = "We use lazy_static for cross-crate compatibility"
# Global settings
[settings]
offline = true
max_suggestions = 10
[code_audit]
ignore_paths = ["src/generated", "tests/fixtures"]
ignore_kinds = ["UnwrapAbuse"]Or pass a custom path: cargo bless --policy=custom-bless.toml
Synthetic screenshots below are trimmed for readability; your tree will differ.
π cargo-bless v0.4.1
π Summary β scanned 1 workspace member
β’ my-crate β 42 direct deps, 580 total in resolve
Suggestions after policy: 7
By impact β high: 3, medium: 3, low: 1
Top patterns:
β’ serde_derive β serde with "derive" feature
β’ tracing-subscriber+parking_lot β tracing-subscriber without parking_lot
β¦
`--fix` changes Cargo.toml entries only β never Rust source.
$ cargo bless --audit-code
π cargo-bless v0.4.1
π 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
β¦
latest: v0.13.2, 64.6M recent downloads
(This sample shows only a `[LOW]` impact row β real trees often surface `[HIGH]` items too.)
𧨠Bullshit detector code audit
Scanned 8 Rust files.
π¨ Bullshit detected: 2 findings
β’ unwrap abuse src/main.rs:14:35
Fix: Propagate the error with ?, add context, or handle the failure explicitly.
$ cargo bless --fix --dry-run
π Dry-run β previewing Cargo.toml edits only (no writes, no cargo update)
π Dry-run: the following changes would be made:
--- Cargo.toml (original)
+++ Cargo.toml (modified)
- serde_json = "1"
Changes that would be applied:
β Removed `serde_json`, enabled `json` feature on `reqwest`
{
"cargo_bless_version": "0.4.1",
"workspace_scan": false,
"packages": [
{
"name": "my-crate",
"version": "0.5.1",
"manifest_path": "/tmp/demo/Cargo.toml",
"dependency_suggestions": [
{
"kind": "StdReplacement",
"current": "lazy_static",
"recommended": "std::sync::LazyLock",
"impact": "High",
"confidence": "High",
"migration_risk": "Low",
"autofix_safety": "ManualOnly",
"reason": "β¦"
}
]
}
],
"code_audit": null
}jobs:
bless:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Install cargo-bless
run: cargo install cargo-bless
- name: Lint dependency choices
run: cargo bless --offline --fail-on=highCombine with --json in a dedicated job if you want to upload artifacts rather than stare at ANSI colors.
Before
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
serde_json = "1"After (conceptual β cargo bless --fix)
[dependencies]
reqwest = { version = "0.12", features = ["json"] }
# serde_json dropped β responses use reqwest's json pathEach 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.
Only suggestions marked autofix_safety = "CargoTomlOnly" are auto-fixable by cargo bless --fix.
StdReplacement, Unmaintained, ModernAlternative, and ComboWin are reported but not auto-fixed by default β they usually require source code changes or architectural judgment.
Before any write, --fix creates a Cargo.toml.bak backup and runs cargo update afterward. Use --dry-run to preview the diff without touching files.
cargo bless bs --fix is a separate, source-level auto-fixer: it replaces every .unwrap() call with .expect("TODO: handle this") across all flagged files (writes *.rs.bak backups). Use --dry-run to preview. Only UnwrapAbuse findings are touched β the transform is mechanical and safe.
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- Security advisories are fetched in a single batch call to osv.dev using each direct dependency's exact resolved version (skipped with
--offlineor--no-advisories; non-fatal) - With
--audit-codeorcargo bless bs, the bullshit detector scans Rust files undersrc/by default (opt in totests/,examples/,benches/with--include-tests);#[test]and#[cfg(test)]blocks are masked via tree-sitter so test code never pollutes the report toml_editapplies fixes while preserving comments and formatting
Network calls are non-fatal β if you're offline, the rule-based report still works.
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
This project builds directly on work by many others β both in the Rust ecosystem and across the collaborators who got it here.
cargo-bless did not start from scratch. It inherits the rigor of its ancestors:
- The Bullshit Buster MCP era β where the habit started: a handful of small checkers with deliberately silly names, turned loose at the end of a session on our own work. Never about building a case against anyone. We just cared whether the thing was actually right. Worked out alongside the Niodoo framework.
- The Bullshit Buster crate β the same habit, made permanent. The
bsdetector in this tool is its direct descendant. (Temporarily off crates.io; it will be restored.) cargo-blessβ the same question aimed at dependencies instead of code: "is this dependency tree modern, boring, and defensible?"
That's why this tool reports confidence, migration risk, and evidence source instead of just barking at you. It was built by people checking their own homework, so it tries to give you what you'd want when checking yours.
Everything above came out of one long, ongoing conversation β not divided-up tasks. The ideas were argued into shape in dialogue, and there is no clean seam where one contributor's thinking stops and another's begins. So this is a list of who was in the room, not a split of who did what:
- Jason Van Pham β author and maintainer.
- Grok, Claude, and GPT β thinking partners throughout, from the earliest Bullshit Buster conversations to this release.
- Echo, Shep, and Lumina β substantial work on this project. π
- blessed.rs by nicoburns and contributors (core curated recommendations and patterns).
- Authors and maintainers of its dependencies: clap, cargo_metadata, toml_edit, reqwest, serde, tree-sitter, and others (full list in Cargo.toml).
- Data sources: crates.io, GitHub, osv.dev.
Thank you to everyone maintaining these projects and the broader Rust community.
This project is licensed under the MIT License β see LICENSE-MIT.
The license field in Cargo.toml declares the license for the published crate. Dependency licenses are declared by their respective crates (visible on crates.io or via cargo metadata). This tool itself is not a license compliance scanner (see cargo deny, cargo about, etc. for that).
