Documentation

Publishing Documentation

When you publish a library crate to crates.io via cargo publish, docs.rs automatically downloads your crate archive, builds its documentation in an isolated container, and hosts the generated HTML at https://docs.rs/<crate_name>/<version>. For private or application repositories, static target/doc/ output can be deployed directly to GitHub Pages, Cloudflare Pages, or an internal web server.

`cargo publish` ---> crates.io ---> Triggers docs.rs build queue
                                            |
                                            v
                              Reads `[package.metadata.docs.rs]`
                              Runs `rustdoc` inside sandboxed container
                                            |
                                            v
                              Published at `https://docs.rs/<crate>`

Configuring docs.rs Builds in Cargo.toml

By default, docs.rs builds your crate on x86_64-unknown-linux-gnu with default features only. If your crate has optional Cargo features (such as serde, tokio, or tls) that enable additional modules or trait implementations, configure the [package.metadata.docs.rs] table in Cargo.toml so docs.rs enables all features during documentation builds:

[package]
name = "my_network_kit"
version = "0.2.0"
edition = "2024"
description = "Fast framing utilities for network streams"
license = "MIT OR Apache-2.0"
repository = "https://github.com/example/my_network_kit"
documentation = "https://docs.rs/my_network_kit"
readme = "README.md"

[features]
default = []
serde = []
async-io = []

[package.metadata.docs.rs]
# Build documentation on docs.rs with all optional features enabled
all-features = true
# Pass "--cfg docsrs" to rustdoc so unstable `doc_cfg` badges can be rendered
rustdoc-args = ["--cfg", "docsrs"]
# Optionally build docs for additional target triples
targets = ["x86_64-unknown-linux-gnu", "aarch64-apple-darwin", "x86_64-pc-windows-msvc"]

Rendering Feature Badges with doc_cfg / doc_auto_cfg

When [package.metadata.docs.rs] passes --cfg docsrs (which runs on docs.rs's nightly rustdoc builder), enabling #![cfg_attr(docsrs, feature(doc_auto_cfg))] at the top of src/lib.rs automatically renders a blue "Available on crate feature serde only" badge next to every #[cfg(feature = "serde")] item—while still compiling cleanly on stable Rust during normal cargo build and cargo test runs!

// Compiles cleanly on stable Rust; activates `doc_auto_cfg` only when `--cfg docsrs` is passed
#![cfg_attr(docsrs, feature(doc_auto_cfg))]

/// Core frame type always available.
#[derive(Debug)]
pub struct Frame(pub Vec<u8>);

/// Available only when the `"compression"` feature is enabled.
#[cfg(feature = "compression")]
pub fn compress_frame(frame: &Frame) -> Frame {
    Frame(frame.0.clone())
}

fn main() {
    let f = Frame(vec![1, 2, 3]);
    println!("Frame length: {}", f.0.len());
}
Frame length: 3

Avoiding Deduplication Drift with include_str!("../README.md")

To keep your repository's README.md and your crate's top-level src/lib.rs documentation identical—and to have cargo test --doc test every code example inside README.md—embed README.md directly at the top of src/lib.rs:

#![doc = include_str!("../README.md")]

Pre-Publish Local Verification Checklist

Before running cargo publish or pushing a release tag, run these three commands locally to verify your documentation will build cleanly on docs.rs:

# 1. Verify no broken intra-doc links or rustdoc warnings with all features enabled
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features

# 2. Verify all doc-tests compile and pass
cargo test --doc --all-features

# 3. Verify package tarball includes README.md and all required files
cargo package --list