| Crates.io | cargo-anatomy |
| lib.rs | cargo-anatomy |
| version | 0.6.8 |
| created_at | 2025-07-16 04:07:54.802779+00 |
| updated_at | 2026-01-17 02:38:47.607579+00 |
| description | Analyze Rust workspaces and report package metrics |
| homepage | https://github.com/cutsea110/cargo-anatomy |
| repository | https://github.com/cutsea110/cargo-anatomy |
| max_upload_size | |
| id | 1754882 |
| size | 219,832 |
cargo-anatomy analyzes Rust workspaces and calculates metrics inspired by Robert C. Martin's package metrics. Each crate inside the workspace is treated as a package.
cargo install cargo-anatomy
struct, enum, trait and type definitions).H = (R + 1) / N.A = abstract_classes / N.I = Ce / (Ce + Ca).D = |A + I - 1| / sqrt(2).D' = |A + I - 1|.Each metric is also mapped to a qualitative label. These labels are assigned using the following thresholds:
abstract, ≤ 0.3 is concrete, otherwise mixed.high, otherwise low.unstable, ≤ 0.3 is stable, otherwise moderate.good.useless if A + I - 1 ≥ 0, otherwise painful.balanced.
cargo-anatomy also reports the list of classes discovered in each crate and detailed dependency graphs when invoked with the -a flag.# Run on the current workspace
cargo anatomy
# Analyze a specific manifest
cargo anatomy --manifest-path path/to/Cargo.toml
# Show detailed class and dependency information
cargo anatomy -a
# Include external dependencies in metrics (may be slower)
cargo anatomy -x
# Use a custom evaluation config generated by `cargo anatomy init` below
cargo anatomy -c config.toml
# Generate a template config file which you can modify and use with `-c`
cargo anatomy init
# Display help with metric descriptions
cargo anatomy -?
# Show version
cargo anatomy -V
# Output in YAML format
cargo anatomy -o yaml
# Output in Graphviz DOT format
cargo anatomy -o dot
# Output in Mermaid format
cargo anatomy -o mermaid
# Fail if metrics violate thresholds (experimental)
cargo anatomy --h-lt 1.1 --d-prime-ge 0.9
For custom evaluation thresholds, run cargo anatomy init to generate a
template configuration and pass -c <FILE> to load it. See the Configuration section for more details.
The command outputs metrics for every member crate in compact JSON format by default. Use -x to also analyze external dependencies. Analyzing external crates can significantly increase processing time. When the -a flag is used, each crate also includes a details.kind field indicating whether it is part of the workspace or an external crate. Pipe to jq if you want it pretty printed. Use -o yaml for YAML output, -o dot for Graphviz or -o mermaid for Mermaid diagrams. When using -o dot, you can write the graph to a file and convert it with Graphviz: cargo anatomy -o dot > graph.dot && dot -Tpng graph.dot -o graph.png. Dependency arrows are labeled with the efferent couple count from the source crate when the -a flag is used. Graphviz and Mermaid diagrams can include individual type nodes when --show-types-crates=<CRATE1,CRATE2> is specified. Mermaid will only render the first 500 edges by default, so increase maxEdges in your Mermaid configuration if your graph is larger. Both Graphviz and Mermaid outputs omit dependency edges unless -a is supplied, so combining these formats with -a is recommended when you want to visualize the graph.
Use --show-types-crates-all to expand all workspace crates with type details (experimental).
cargo-anatomy only sees the code that exists in your source files. Dependencies
introduced by macros are not visible unless you expand them first. You can use
cargo expand to generate expanded
sources and analyze those instead.
# Install cargo-expand if you don't have it
cargo install cargo-expand
# Produce expanded sources for a crate
cargo expand -p my_crate --lib > /tmp/my_crate/src/lib.rs
cp my_crate/Cargo.toml /tmp/my_crate/
# If the crate inherits dependencies from the workspace, also copy the workspace root
# Cargo.toml or replace `workspace = true` entries with explicit versions.
# Run cargo-anatomy on the expanded copy
cargo anatomy --manifest-path /tmp/my_crate/Cargo.toml
Repeat these steps for any crates that rely heavily on macros to ensure macro-generated types are included in the analysis.
If the copied manifest contains dependencies like anyhow = { workspace = true },
ensure the workspace root Cargo.toml is copied alongside or replace those
entries with concrete versions; otherwise cargo metadata will report
"failed to find a workspace root".
See docs/output-schema.md for a description of the output schema. Example output (| jq):
{
"meta": {
"cargo-anatomy": { "version": "0.6.8", "target": "linux/x86_64" },
"config": {
"evaluation": {
"abstraction": { "abstract_min": 0.7, "concrete_max": 0.3 },
"cohesion": { "high_gt": 1.0 },
"instability": { "unstable_min": 0.7, "stable_max": 0.3 },
"distance": { "good_max": 0.4, "bad_min": 0.6 }
}
}
},
"crates": [
{
"crate_name": "my_crate",
"metrics": {
"n": 3,
"r": 1,
"h": 0.67,
"ca": 0,
"ce": 1,
"a": 0.33,
"i": 1.0,
"d": 0.24,
"d_prime": 0.34
},
"evaluation": {
"a": "mixed",
"h": "low",
"i": "unstable",
"d_prime": "good"
},
"details": {
"kind": "Workspace",
"classes": [
{ "name": "Foo", "kind": "Struct" },
{ "name": "Bar", "kind": "Struct" },
{ "name": "MyTrait", "kind": "Trait" }
]
}
}
],
"warnings": {
"dependency_cycles": []
}
}
Enable RUST_LOG=info to see progress logs during analysis.
cargo-anatomy looks for a .anatomy.toml file at the workspace root to customize how metric values are evaluated. Run cargo anatomy init to create a template .anatomy.toml in the current directory. Pass -c <FILE> to use a different configuration. The file is written in TOML and contains the following sections and defaults:
[evaluation]
[evaluation.abstraction]
abstract_min = 0.7 # minimum ratio considered abstract
concrete_max = 0.3 # maximum ratio considered concrete
[evaluation.cohesion]
high_gt = 1.0 # values greater than this are high cohesion
[evaluation.instability]
unstable_min = 0.7 # minimum ratio considered unstable
stable_max = 0.3 # maximum ratio considered stable
[evaluation.distance]
good_max = 0.4 # max normalized distance considered good
bad_min = 0.6 # min normalized distance considered bad
Specify a path with -c <FILE> to use a different configuration, or omit the option to rely on these defaults.
A pre-built container is available on Docker Hub. Replace <version> with the
desired tag and mount your workspace into /work:
docker run --rm -v $(pwd):/work cutsea110/cargo-anatomy:<version> [ARGS...]
Any arguments after the image name are forwarded to cargo-anatomy. The image
includes the toolchain cargo binary and sets the CARGO environment variable
to that path, so cargo metadata works without rustup.
Build an image for the current architecture and load it into Docker with:
docker buildx build --platform <arch> -t cargo-anatomy --load .
Replace <arch> with linux/amd64 on x86_64 machines or linux/arm64 on
Arm-based hosts. To publish a multi-platform image, use --push instead of
--load:
docker buildx build --platform linux/amd64,linux/arm64 \
-t <your-registry>/cargo-anatomy:<version> --push .
Set <version> to the tag for the published image. After building or pulling an
image, run it as shown above. The runtime uses a distroless base for a smaller
footprint.
You can integrate cargo-anatomy in your CI pipeline. The example below installs
cargo-anatomy and fails the job when metrics do not satisfy the configured thresholds.
Make sure a .anatomy.toml file is present in your repository so the workflow
can load your evaluation settings. You can generate a template with
cargo anatomy init and commit it to version control.
# .github/workflows/anatomy.yml
name: cargo-anatomy
on:
push:
branches: [ main ]
pull_request:
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-rust@v1
with:
rust-version: stable
- name: Install cargo-anatomy
run: cargo install cargo-anatomy
- name: Run cargo-anatomy
run: cargo anatomy -c .anatomy.toml --h-lt 1.1 --d-prime-ge 0.9