| Crates.io | cargo-public-api |
| lib.rs | cargo-public-api |
| version | 0.50.1 |
| created_at | 2022-04-06 03:40:41.661411+00 |
| updated_at | 2025-08-02 17:31:46.448667+00 |
| description | List and diff the public API of Rust library crates between releases and commits. Detect breaking API changes and semver violations via CI or a CLI. |
| homepage | https://github.com/cargo-public-api/cargo-public-api |
| repository | https://github.com/cargo-public-api/cargo-public-api |
| max_upload_size | |
| id | 562910 |
| size | 246,908 |
List and diff the public API of Rust library crates between releases and commits. Detect breaking API changes and semver violations via CI or a CLI. Relies on and automatically builds rustdoc JSON, for which a recent version of the Rust nightly toolchain must be installed.
Install the cargo public-api subcommand with a recent regular stable Rust toolchain:
cargo +stable install cargo-public-api --locked
Ensure nightly-2025-08-02 or later is installed (does not need to be the active toolchain) so cargo public-api can build rustdoc JSON for you:
rustup install nightly --profile minimal
This example lists the public API of the regex crate. First we clone the repo:
git clone https://github.com/rust-lang/regex ; cd regex
Now we can list the public API of regex by running
cargo public-api
which will print the public API of regex with one line per public item in the API:
To diff the public API of the regex crate in the current directory against published version 1.6.0 on crates.io:
cargo public-api diff 1.6.0
cargo public-api diff latest
cargo public-api diff ref1..ref2
With a regular cargo test that you run in CI you will be able to
First add the latest versions of the recommended libraries to your [dev-dependencies]:
cargo add --dev \
rustup-toolchain \
rustdoc-json \
public-api \
insta
Then add the following test to your project. As the author of the below test code, I hereby associate it with CC0 and to the extent possible under law waive all copyright and related or neighboring rights to it:
#[test]
fn public_api() {
// Install a compatible nightly toolchain if it is missing
rustup_toolchain::install(public_api::MINIMUM_NIGHTLY_RUST_VERSION).unwrap();
// Build rustdoc JSON
let rustdoc_json = rustdoc_json::Builder::default()
.toolchain(public_api::MINIMUM_NIGHTLY_RUST_VERSION)
.build()
.unwrap();
// Derive the public API from the rustdoc JSON
let public_api = public_api::Builder::from_rustdoc_json(rustdoc_json)
.build()
.unwrap();
// Assert that the public API looks correct
insta::assert_snapshot!(public_api);
}
Before you run the test the first time you need to bless the current public API:
INSTA_UPDATE=always cargo test
This creates a tests/snapshots/<module>_public_api.snap file in your project that you git add together with your other project files. Then a regular
cargo test
will fail if your public API is accidentally or deliberately changed. Run
INSTA_UPDATE=always cargo test
again to review and accept public API changes.
For completeness, items belonging to Blanket Implementations, Auto Trait Implementations, and Auto Derived Implementations, such as
impl<T, U> Into<U> for T where U: From<T>impl Sync for ...impl Debug for ... / #[derive(Debug)]are included in the list of public items by default. Use
--omit blanket-impls--omit auto-trait-impls--omit auto-derived-implsrespectively to omit such items from the output to make it much less noisy:
cargo public-api --omit blanket-impls,auto-trait-impls,auto-derived-impls
For convenience you can also use -s (--simplified) to achieve the same thing. This is a shorter form of the above command:
cargo public-api -sss
| Version | Understands the rustdoc JSON output of |
|---|---|
| 0.50.x | nightly-2025-08-02 — |
| 0.49.x | nightly-2025-07-17 — nightly-2025-08-01 |
| 0.48.x | nightly-2025-06-22 — nightly-2025-07-16 |
| 0.47.x | nightly-2025-03-24 — nightly-2025-06-21 |
| 0.46.x | nightly-2025-03-16 — nightly-2025-03-23 |
| 0.45.x | nightly-2025-03-14 — nightly-2025-03-15 |
| earlier versions | see here |
See CONTRIBUTING.md.
"Rust" and "Cargo" are trademarks of the Rust Foundation. This project is not affiliated with, endorsed by, or otherwise associated with the Rust Project or Rust Foundation.
As a workaround for https://github.com/mitsuhiko/insta/issues/780 you might want to put *.snap linguist-language=txt in your .gitattributes. ↩