cargo-anatomy
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.
Installation
cargo install cargo-anatomy
Metrics
- N — number of classes in the crate (
struct,enum,traitandtypedefinitions). - R — number of internal class relationships. Each unique reference from one class to another within the same crate counts once.
- H — relational cohesion:
H = (R + 1) / N. - Ca — afferent coupling: the number of external classes that depend on types from this crate.
- Ce — efferent coupling: the number of classes in this crate that depend on types from other crates in the workspace.
- A — abstraction: ratio of abstract classes (traits) to total classes,
A = abstract_classes / N. - I — instability:
I = Ce / (Ce + Ca). - D — distance from the main sequence:
D = |A + I - 1| / sqrt(2). - D' — normalized distance from the main sequence:
D' = |A + I - 1|.
Evaluation
Each metric is also mapped to a qualitative label. These labels are assigned using the following thresholds:
- A (abstraction): ≥ 0.7 is
abstract, ≤ 0.3 isconcrete, otherwisemixed. - H (cohesion): > 1.0 is
high, otherwiselow. - I (instability): ≥ 0.7 is
unstable, ≤ 0.3 isstable, otherwisemoderate. - D' (normalized distance):
- ≤ 0.4 →
good. - ≥ 0.6 →
uselessifA + I - 1 ≥ 0, otherwisepainful. - otherwise
balanced.cargo-anatomyalso reports the list of classes discovered in each crate and detailed dependency graphs when invoked with the-aflag.
- ≤ 0.4 →
Usage
# Run on the current workspace
# Show detailed class and dependency information
# Include external dependencies in metrics (may be slower)
# Display help with metric descriptions
# Show version
# Output in YAML format
# Output in Graphviz DOT format
# Output in Mermaid format
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 outputs omit dependency edges unless -a is supplied, so combining these formats with -a is recommended when you want to visualize the graph.
See docs/output-schema.md for a description of the output schema. Example output (| jq):
Enable RUST_LOG=info to see progress logs during analysis.
Docker image
Using the official image
A pre-built container is available on Docker Hub. Replace <version> with the
desired tag and mount your workspace into /work:
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.
Building an image (for developers)
Build an image for the current architecture and load it into Docker with:
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:
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.