cargo_metadata
Structured, strongly-typed Rust access to the JSON output of `cargo metadata` and `cargo --message-format=json`.
Repository Health
Technical Analysis
cargo_metadata is a Rust library that turns the raw JSON produced by cargo metadata into strongly-typed, ergonomic structs so you can inspect a workspace’s packages, dependencies, targets, features, and resolve graph without hand-parsing serde_json values. It also models the streaming --message-format=json output emitted during builds, letting cargo-* subcommands react to compiler messages, artifacts, build-script runs, and diagnostics.
It is the de-facto standard building block for the Rust tooling ecosystem: linters, coverage tools, custom subcommands, and CI utilities lean on it to understand the shape of a project and to consume cargo’s machine-readable output. The crate wraps invocation, feature/flag configuration, and deserialization behind a small MetadataCommand builder and a set of well-documented types.
What You Get
- A
MetadataCommandbuilder that invokescargo metadata, forwards--manifest-path, feature flags, and extra args, then deserializes the result. - Strongly-typed
Metadata,Package,Dependency,Target,Resolve, andNodestructs covering the full workspace graph. - A streaming
MessageAPI (parse_stream) modeling compiler messages, artifacts, build-script output, and build-finished events from--message-format=json. - Serde-based serialization and deserialization, so subcommands can both consume and re-emit cargo-compatible JSON.
- Re-exports of
camino,cargo_platform, andsemverso version and path types line up with the rest of the cargo ecosystem.
Common Use Cases
- Building a
cargo-*subcommand that needs to know the workspace’s packages, targets, and dependency graph. - Writing linters, coverage collectors, or CI tools that consume cargo’s
--message-format=jsonbuild output. - Resolving feature sets and dependency kinds (normal, dev, build) programmatically before running an operation.
- Generating
--message-format=json-like output from your own tooling by reusing the shared types.
Under The Hood
Architecture - The crate centers on src/lib.rs (~47KB), which defines the Metadata, Package, Dependency, Target, Resolve, and Node types plus the MetadataCommand builder. MetadataCommand::exec shells out to cargo metadata --format-version 1, captures stdout, and deserializes it via serde_json (with unbounded_depth enabled for deep graphs). Streaming build output is handled separately in src/messages.rs, where Message::parse_stream wraps a BufRead and yields typed CompilerMessage, Artifact, BuildScript, and BuildFinished variants; diagnostics live in src/diagnostic.rs. Errors flow through a single thiserror-derived enum in src/errors.rs.
Tech Stack - Pure Rust (edition 2021, rust-version 1.88). Core dependencies are serde + serde_json for (de)serialization, semver for version types, camino for UTF-8 paths, cargo-platform for target specs, and thiserror for errors. An optional builder feature pulls in derive_builder to generate builder types for the message structs; an unstable feature gates libtest message parsing. No async runtime and no heavy transitive footprint.
Code Quality - The crate enforces #![deny(missing_docs)], so every public item is documented, and the module-level docs carry runnable doctests for the primary flows. Tests are organized under tests/ with test_samples.rs and selftest.rs plus fixture workspaces in tests/all and tests/basic_workspace that exercise real cargo output across dependency kinds, renamed deps, and rust-version fields. Errors are modeled explicitly rather than panicking, and a str_newtype! macro keeps the many string-wrapper types consistent.
API Design - The public surface is small and discoverable: a fluent MetadataCommand builder for the common path, plus plain data structs you can pattern-match. Getting metadata is a one-liner (MetadataCommand::new().exec().unwrap()), and forwarding --manifest-path or features is a couple of chained calls. Re-exporting camino, semver, and cargo_platform avoids version-mismatch friction, and the streaming Message enum reads naturally in a for/match loop. Documentation on docs.rs is thorough and example-driven.
Used by 2 apps in this directory
Fyrox
Game Development
A production-ready 2D/3D game engine written in Rust with a built-in scene editor, physics, and hot-reloading game scripts
Meilisearch
Search
Lightning-fast hybrid search engine with AI-powered semantic and full-text retrieval for modern applications.