Publishing to crates.io
Publishing a crate to crates.io makes it available to the ecosystem via cargo add. Success requires correct metadata, semver discipline, and a clean cargo package dry run.
Search across all documentation pages
Publishing a crate to crates.io makes it available to the ecosystem via cargo add. Success requires correct metadata, semver discipline, and a clean cargo package dry run.
cargo publish --dry-run
cargo package --list
cargo login # one-time token
cargo publish[package]
license = "MIT OR Apache-2.0"
description = "Short summary"
repository = "https://github.com/you/crate"When to reach for this: Sharing a library beyond your workspace or open-sourcing reusable Rust code.
Prepare and publish version 0.2.0:
[package]
name = "valid-types"
version = "0.2.0"
edition = "2024"
rust-version = "1.97"
license = "MIT OR Apache-2.0"
description = "Newtypes for domain identifiers"
repository = "https://github.com/acme/valid-types"
readme = "README.md"
keywords = ["newtype", "validation"]
categories = ["development-tools"]
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]cargo test --all-features
cargo doc --no-deps
cargo publish --dry-run
cargo publishWhat this demonstrates:
docs.rs metadata builds docs with all features0.1.0| Step | Command |
|---|---|
| Tests green | cargo test --all-features |
| Clippy clean | cargo clippy -- -D warnings |
| Docs build | cargo doc --no-deps |
| Tarball sane | cargo package --list |
| License files present | LICENSE-MIT, LICENSE-APACHE |
0.y.z - treat minor y as breaking for pre-1.0 crates (ecosystem convention)1.0.0 - stable API promise; breaking changes need major bumpcargo yank --version 0.1.1license field.path = "../...". Fix: publish dependencies first or use version deps only.cargo-semver-checks in CI for libraries.target/ or data - use exclude in Cargo.toml. Fix: cargo package --list review.cargo login interactive or CI secret CARGO_REGISTRY_TOKEN.| Alternative | Use When | Don't Use When |
|---|---|---|
| Private registry | Internal crates only | Open-source ecosystem crates |
| Git dependency | Pre-release consumers | Stable public API |
cargo install from git | CLI tools not libraries | Reusable library code |
crates.io policy discourages deletion. Yank bad versions and publish fixes.
Run cargo publish -p crate_name from the workspace root; ensure path deps are published or replaced with version deps.
Use scoped tokens for CI (publish-only, limited crates) instead of full account tokens.
Automatically on publish. Configure [package.metadata.docs.rs] for features and --cfg docsrs for doc attributes.
Start 0.1.0 while API is evolving; move to 1.0.0 when you commit to stable semver.
cargo package then cargo install --path target/package/name-version.crate in a temp project.
Transfer policy exists for squatting disputes; pick unique names early with cargo search.
crates.io is for libraries; distribute CLIs via cargo install your-cli after publishing the crate with a [[bin]].
When meaningful fixes or features land; avoid churn releases without changelog entries.
No. CI must gate cargo publish on green cargo test and clippy.
cargo new --libStack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 16, 2026