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|.
cargo-anatomy also reports the list of classes discovered in each crate and detailed dependency graphs when invoked with the -a flag.
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
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. Each crate in the results includes a 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.
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
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.
Run the container on your project by mounting the 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. The runtime uses a
distroless base for a smaller footprint.