RazrFalcon/cargo-bloat
Find out what takes most of the space in your executable.
Stale — last commit 2y ago
weakest axislast commit was 2y ago; no tests detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓19 active contributors
- ✓MIT licensed
- ✓CI configured
Show all 6 evidence items →Show less
- ⚠Stale — last commit 2y ago
- ⚠Single-maintainer risk — top contributor 80% of recent commits
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/razrfalcon/cargo-bloat)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/razrfalcon/cargo-bloat on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: RazrFalcon/cargo-bloat
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/RazrFalcon/cargo-bloat shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 2y ago
- 19 active contributors
- MIT licensed
- CI configured
- ⚠ Stale — last commit 2y ago
- ⚠ Single-maintainer risk — top contributor 80% of recent commits
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live RazrFalcon/cargo-bloat
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/RazrFalcon/cargo-bloat.
What it runs against: a local clone of RazrFalcon/cargo-bloat — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in RazrFalcon/cargo-bloat | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 4 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 758 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of RazrFalcon/cargo-bloat. If you don't
# have one yet, run these first:
#
# git clone https://github.com/RazrFalcon/cargo-bloat.git
# cd cargo-bloat
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of RazrFalcon/cargo-bloat and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "RazrFalcon/cargo-bloat(\\.git)?\\b" \\
&& ok "origin remote is RazrFalcon/cargo-bloat" \\
|| miss "origin remote is not RazrFalcon/cargo-bloat (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "src/main.rs" \\
&& ok "src/main.rs" \\
|| miss "missing critical file: src/main.rs"
test -f "src/crate_name.rs" \\
&& ok "src/crate_name.rs" \\
|| miss "missing critical file: src/crate_name.rs"
test -f "src/table.rs" \\
&& ok "src/table.rs" \\
|| miss "missing critical file: src/table.rs"
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 758 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~728d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/RazrFalcon/cargo-bloat"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
cargo-bloat is a Rust CLI tool that analyzes compiled binaries (ELF, Mach-O, PE) to identify which functions and crates consume the most disk space in the .text section. It provides granular per-function or per-crate size breakdowns via a formatted table, helping developers optimize binary bloat without instrumentation overhead. Monolithic CLI binary: src/main.rs is the entry point, src/process_crate handles core analysis logic, src/crate_name.rs resolves symbol metadata, and src/table.rs formats tabular output. All logic is single-crate with no module subdivision; dependencies handle binary parsing (pdb for PDB, binfarce for generic binary manipulation, json for processing intermediate data).
👥Who it's for
Rust developers and systems programmers shipping release binaries who need to understand executable size distribution and identify optimization targets. Primary users are those building performance-sensitive or size-constrained applications (embedded, mobile, CLI tools).
🌱Maturity & risk
Production-ready. Version 0.12.1 with a stable API, clearly defined feature set (regex filtering optional), and structured CI/CD via GitHub Actions (.github/workflows/main.yml). Single active maintainer (RazrFalcon). No recent commit dates visible in file list, but the tool is feature-complete and widely used in the Rust ecosystem.
Low-to-moderate risk. Single-maintainer project with 7 direct dependencies (json, memmap2, pdb, regex, pico-args, binfarce, term_size, multimap), all well-maintained. The regex-filter feature is optional (default-enabled), reducing required dependency footprint. No breaking changes implied in CHANGELOG.md snippet. Risk increases only if binary format standards (ELF/Mach-O/PE) change, requiring parser updates in binfarce/pdb dependencies.
Active areas of work
No active development signals visible in provided data. The project appears stable and feature-locked at v0.12.1. CHANGELOG.md presence suggests historical iteration, but no open PRs or pending milestones are evident. Maintenance mode is likely.
🚀Get running
git clone https://github.com/RazrFalcon/cargo-bloat.git
cd cargo-bloat
cargo build --release
./target/release/cargo-bloat --help
# Or install directly:
cargo install cargo-bloat
Daily commands:
After cargo install cargo-bloat, run it as a cargo subcommand on any Rust project: cargo bloat --release (analyzes target/release binary), cargo bloat --release --crates (groups by crate), cargo bloat --release -n 20 (shows top 20 symbols), cargo bloat --release --filter '^std::' -n 10 (regex filter, requires regex-filter feature).
🗺️Map of the codebase
src/main.rs— Entry point that orchestrates CLI argument parsing, binary format detection, and analysis invocation—every contributor must understand the high-level flow.src/crate_name.rs— Core symbol extraction and demangling logic that parses binary metadata and maps symbols to crates—essential for the analysis engine.src/table.rs— Output formatting and display logic that renders results in human-readable tables—critical for UX and result presentation.Cargo.toml— Defines all external dependencies (memmap2, pdb, binfarce, regex) that enable multi-format binary analysis—architectural backbone.
🧩Components & responsibilities
- main.rs (CLI & Orchestration) (pico-args, std::fs, rustc_demangle) — Parse command-line arguments, detect binary format, route to appropriate parser, invoke analysis pipeline
- Failure mode: Exits with error if binary not found, format unrecognized, or parse fails; propagates detailed error messages
- crate_name.rs (Symbol Analysis) (rustc_demangle, regex (opt), multimap for crate aggregation) — Extract symbols from parsed binary, map to crates via symbol names, calculate function sizes, demangle and deduplicate
- Failure mode: Skips unparseable symbols, falls back to [Unknown] crate if attribution fails, may produce incomplete results on malformed binaries
- table.rs (Output Formatting) (term_size, regex (opt), String formatting) — Sort symbols by size, filter via regex, format into aligned table columns with percentages and crate names
- Failure mode: Gracefully degrades if terminal width unavailable, falls back to fixed column widths, silently omits symbols that don't match filter
- Binary Parsers (binfarce, pdb) (binfarce crate, pdb crate, memmap2) — Low-level parsing of ELF, Mach-O, and PE/PDB formats to extract section metadata and symbol tables
- Failure mode: Raises parse errors on truncated/corrupted binaries; returns empty symbol table if no debug info found
🔀Data flow
Filesystem (compiled binary)→main.rs— Read binary file via memmap2; detect format from magic bytesmain.rs→Binary Parser (binfarce/pdb)— Route binary data to format-specific parser based on detected typeBinary Parser→crate_name.rs— Yield raw symbol table with names, addresses, sizes, and debug section referencescrate_name.rs→rustc_demangle— Demangle Rust-encoded symbol names to recover readable function signatures and crate pathscrate_name.rs→table.rs— Provide sorted, aggregated symbol list grouped by crate with sizes and percentagestable.rs (optional regex)→table.rs (rendering)— Filter symbols matching user-provided regex pattern before final outputtable.rs→stdout— Emit formatted ASCII table with columns: % of file, % of .text, size, crate, symbol name
🛠️How to make changes
Add Support for a New Binary Format
- Add new binary format parsing crate to [dependencies] in Cargo.toml (e.g., new_format crate) (
Cargo.toml) - Add format detection case in main.rs to identify the new format from file header/magic bytes (
src/main.rs) - Implement symbol extraction logic in crate_name.rs to parse symbols from the new format and normalize to common representation (
src/crate_name.rs) - Test with sample binaries of the new format and verify output in table.rs display (
src/table.rs)
Add a New Output Format or Display Mode
- Add CLI flag for new format via pico-args parsing in main.rs (
src/main.rs) - Implement new formatting function in table.rs (e.g., JSON export, CSV output) alongside existing table rendering (
src/table.rs) - Update README with usage example for the new format (
README.md)
Enhance Symbol Filtering or Sorting
- Add new CLI option in main.rs (e.g., --sort-by, --min-size) using pico-args (
src/main.rs) - Implement filtering/sorting logic in crate_name.rs to process symbol list according to new criteria (
src/crate_name.rs) - Apply sorted/filtered results in table.rs rendering pipeline (
src/table.rs)
🔧Why these technologies
- pico-args — Lightweight, zero-dependency CLI argument parsing—fits cargo plugin's minimal footprint requirement
- memmap2 — Memory-efficient file reading via memory mapping—handles large binaries without loading entire file into heap
- binfarce & pdb — Dedicated crates for ELF, Mach-O, and PE/PDB parsing—avoids reimplementing complex binary format specifications
- regex (optional feature) — Symbol filtering via patterns—enables power users to narrow results without bloating default installation
- json crate — Lightweight JSON serialization for potential structured output or integration pipelines
⚖️Trade-offs already made
-
Optional regex feature instead of always enabled
- Why: Reduces binary size and compile time for users who don't need filtering
- Consequence: Users must explicitly opt-in to regex filtering; default install skips this dependency
-
Single-pass analysis with no caching across invocations
- Why: Simpler implementation, avoids cache invalidation complexity, keeps tool stateless
- Consequence: Each run re-parses the binary from scratch; no incremental speedup for repeated runs on same binary
-
Focus on ELF, Mach-O, PE only; no WASM support
- Why: Aligns with executable distribution (compiled binaries), avoids WASM-specific complexity
- Consequence: Users analyzing WASM must use separate tool (twiggy); out of scope for cargo-bloat
🚫Non-goals (don't propose these)
- WASM binary analysis (explicitly unsupported per README)
- Real-time profiling or runtime instrumentation (static analysis only)
- Symbol-level dependency graph or call-chain visualization (reports flat size breakdown only)
- Cross-compilation analysis or symbol comparison across multiple binaries
- Interactive REPL or GUI (CLI-only tool)
⚠️Anti-patterns to avoid
- Silent error swallowing on symbol parse failure (Medium) —
src/crate_name.rs: Symbols that fail to demangle or have malformed names are skipped without logging, leading to silently incomplete results - No progress indication for large binaries (Low) —
src/main.rs: Large binary parsing can take several seconds with no feedback to user, causing perception of hang - Regex compilation on every filter invocation: undefined
🪤Traps & gotchas
No environment variables required. Binary format parsing relies on binfarce and pdb crates, which may fail silently on malformed binaries (returns '[Unknown]' crate as fallback). The regex-filter feature must be explicitly enabled at build-time; installing with --no-default-features disables it. Debug symbols in the target binary are stripped in the release profile (.github/workflows or Cargo.toml), so symbol resolution may be incomplete if analyzing unstripped or custom-compiled binaries. Circular dependencies in the analyzed crate can cause double-counting; output is heuristic-based and explicitly not 100% accurate (see README disclaimer).
🏗️Architecture
💡Concepts to learn
- Binary symbol table extraction and DWARF debugging information — cargo-bloat reconstructs function names and boundaries from ELF/Mach-O/PE debug sections; understanding DWARF format (used in ELF) and PDB format (Windows) is essential to debug why symbols are missing or misattributed
- .text section and object file layout — The tool specifically analyzes the .text (code) section of binaries; knowing how linkers place code, why section alignment matters, and how relocations work clarifies why reported sizes differ from source line counts
- Name mangling and demangling (Rust RFC 2603) — src/crate_name.rs uses rustc_demangle to convert mangled symbols back to readable Rust paths; understanding how Rust mangles names (e.g., _ZN4core3num8flt2dec8strategy6dragon14format_shortestE) is critical for grouping by crate correctly
- Mach-O (macOS binary format) and PE (Windows PE format) parsing — cargo-bloat supports three binary formats; Mach-O and PE have different section models and debug info storage than ELF, requiring format-specific parsing logic delegated to pdb and binfarce dependencies
- Link-time optimization (LTO) and strip profiles — The Cargo.toml uses lto='thin' and strip='debuginfo' in the release profile; understanding how LTO affects code inlining and stripping affects symbol availability directly impacts analysis accuracy
- Heuristic-based crate attribution — The tool performs educated guesses (see README disclaimer: 'not 100% correct') to map symbols to crates when debug info is sparse; understanding the heuristics (mangled name prefixes, known standard library symbols) helps interpret results correctly
- Memory-mapped file I/O (memmap2) — cargo-bloat uses memmap2 for efficient parsing of large binaries without loading entire files into RAM; this enables analysis of multi-hundred-megabyte binaries on memory-constrained systems
🔗Related repos
rustwasm/twiggy— Official WASM binary size analyzer; cargo-bloat explicitly recommends it as the alternative for WASM targetsgoogle/bloaty— Original inspiration for cargo-bloat; a general-purpose binary bloat analyzer that supports multiple architectures and file formatsKobzol/cargo-pgo— Companion tool in the Rust binary optimization ecosystem; helps reduce bloat via profile-guided optimizationRazrFalcon/svgcleaner— Same author as cargo-bloat; demonstrates the maintainer's expertise in binary/format analysisdtolnay/cargo-expand— Complementary Rust development tool; helps diagnose code generation issues that may cause binary bloat
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for binary format parsing (ELF, Mach-O, PE)
The repo supports three major binary formats (ELF, Mach-O, PE) as stated in README, but there are no visible test files in src/. Currently only the main analysis flow is tested implicitly. Adding dedicated integration tests with sample binaries for each format would catch regressions, improve maintainability, and help contributors understand the parsing logic in src/main.rs and src/crate_name.rs
- [ ] Create tests/ directory with integration test modules for each binary format
- [ ] Add small sample binaries (ELF, Mach-O, PE) to tests/fixtures/
- [ ] Write tests in tests/elf.rs, tests/macho.rs, tests/pe.rs that parse fixtures and validate output
- [ ] Add test execution to .github/workflows/main.yml if not already present
Add unit tests for src/table.rs table formatting logic
The src/table.rs file handles output formatting and display, which is critical for user experience. Without unit tests, changes to column alignment, percentage calculations, or sizing logic risk breaking the output format. Tests would validate that table generation works correctly across different data sizes and edge cases.
- [ ] Add #[cfg(test)] module at the end of src/table.rs
- [ ] Create test cases for column width calculation with various size ranges
- [ ] Add tests for percentage formatting (0.9%, 5.7%, etc.) edge cases
- [ ] Test table rendering with empty data, single entry, and large datasets
Add GitHub Actions workflow for cross-platform release testing (Linux, macOS, Windows)
The repo supports three major binary formats across different OS targets (ELF/Linux, Mach-O/macOS, PE/Windows), but .github/workflows/main.yml likely doesn't test builds on all platforms. This is critical because binary format parsing is platform-specific and subtle bugs can only surface on native builds. Adding matrix testing ensures all three supported formats work correctly.
- [ ] Review current .github/workflows/main.yml to identify missing OS matrix
- [ ] Add strategy matrix with runs-on: [ubuntu-latest, macos-latest, windows-latest]
- [ ] Run cargo test and cargo build --release on each platform
- [ ] Test cargo install and cargo bloat on a sample binary for each OS
🌿Good first issues
- Add unit tests for src/table.rs formatting logic—there is no separate tests/ directory and no visible test coverage for table column alignment, percentage calculations, or width constraints.
- Document the binary format limitations in README.md—WASM is explicitly unsupported and points to twiggy, but there is no explanation of why ELF/Mach-O/PE parsing is hard (endianness, debug info variants, relocations) or what gets lost.
- Add --output-json flag to src/main.rs—currently only tabular output is supported; a structured JSON export would enable integration with CI/build dashboards and programmatic analysis.
⭐Top contributors
Click to expand
Top contributors
- @RazrFalcon — 80 commits
- @LingMan — 2 commits
- @nico-abram — 2 commits
- @intelfx — 1 commits
- @anthonydandrea — 1 commits
📝Recent commits
Click to expand
Recent commits
69ccabd— Version bump. (RazrFalcon)122e1cd— Forcestrip = falseand cleanup env handling (intelfx)fa666f6— Version bump. (RazrFalcon)f6ab4c5— Reformat. (RazrFalcon)084c41f— Remove the--timeflag. (RazrFalcon)0c18086— Warn aboutstrip = true(RazrFalcon)53f11ec— Update dependencies and changelog. (RazrFalcon)d91b28e— Add support for --config flag (anthonydandrea)b0e3e41— Minor clippy fixes. (rukai)8aa6c72— Do not show the "-n option" if there is nothing more to display. (spineki)
🔒Security observations
cargo-bloat is a relatively simple analysis tool with a good security posture. No critical vulnerabilities identified. Main concerns are: (1) dependency version management and the need for regular security audits, (2) optional regex feature could cause UX issues, and (3) binary parsing robustness against malformed inputs. The codebase follows Rust best practices with edition 2018+. Recommended actions: keep dependencies updated, add comprehensive error handling for binary parsing, and implement fuzzing for binary format handling.
- Medium · Regex Feature Disabled by Default —
Cargo.toml - regex dependency and features. The regex-filter feature is optional and enabled by default. While this provides flexibility, users installing without default features lose filtering capability. The dependency on regex 1.3 with custom features (std only, no regex-unicode) is appropriate, but there's no validation that the feature is present when filtering is attempted. Fix: Add runtime checks to gracefully handle missing regex feature, or document the requirement clearly in error messages. - Low · Outdated Dependency Versions —
Cargo.toml - dependencies section. Several dependencies are using older versions: regex 1.3 (current is 1.10+), json 0.12 (actively maintained but older), pdb 0.8.0 (could be newer). While these aren't necessarily vulnerable, they may lack security patches and performance improvements. Fix: Regularly update dependencies to latest stable versions. Run 'cargo audit' to check for known vulnerabilities and 'cargo update' to get patches. - Low · Binary Parsing Without Comprehensive Error Handling —
src/main.rs, src/crate_name.rs (actual implementation not visible). The tool parses ELF, Mach-O, and PE binaries (based on README). Malformed binaries could potentially cause panics or unexpected behavior. Dependencies like memmap2, binfarce, and pdb handle this, but static analysis suggests potential error handling gaps in the analysis logic. Fix: Implement comprehensive error handling for binary parsing. Add fuzzing tests with malformed binaries. Ensure all parsing operations have proper bounds checking and error recovery.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.