Rustdoc Integration
Sourcey generates Rust API reference documentation from rustdoc's JSON output. A rustdoc() source tab renders crates, modules, items, and doctests with the same navigation, search, and theming as every other tab type. Anchor IDs follow rustdoc's own conventions, so docs.rs-style deep links into your pages keep resolving.
Requires Sourcey 3.6.1 or later.
How it works
rustdoc emits machine-readable JSON on the nightly toolchain. Sourcey ships a bundled Rust helper crate, sourcey-rustdoc, that runs rustdoc and converts its JSON into a stable v1 RustdocSpec snapshot. The adapter reads that snapshot, either fresh from the helper (live mode) or from a committed file (snapshot mode), and renders static pages.
Prerequisites
Live mode needs a nightly Rust toolchain:
rustup toolchain install nightlySnapshot mode needs no Rust toolchain at all. Commit a generated rustdoc.json and the docs build runs anywhere Node runs.
Configuration
Add a rustdoc() source tab to your config. The manifest path is relative to sourcey.config.ts.
import { defineConfig, rustdoc } from "sourcey";
export default defineConfig({
navigation: {
tabs: [
{
tab: "Rust API",
slug: "rust-api",
source: rustdoc({
manifest: "../Cargo.toml",
mode: "auto",
}),
},
],
},
});For the common case, pass the manifest path directly: rustdoc("../Cargo.toml").
Options
| Option | Default | Description |
|---|---|---|
manifest | . | Path to a Cargo.toml, or a directory containing one |
crates | the manifest package | Crate names to document |
snapshot | none | Path to a committed rustdoc.json snapshot |
mode | "auto" | "auto", "live", or "snapshot" |
features | { default: true } | Feature selection: default, list, all |
includePrivate | false | Include pub(crate) and private items |
includeHidden | false | Include items marked #[doc(hidden)] |
target | host target | Target triple to build docs for |
toolchain | "nightly" | rustup toolchain name (use a dated pin if you need one) |
sourceBasePath | "" | Repository-relative base path for source links |
doctestsIndex | true | Render a dedicated doctests index page |
Modes
auto(default): proberustup toolchain listfor the configured toolchain. If present, run the bundled helper. Otherwise read the snapshot, with an info diagnostic (RUSTDOC_AUTO_FELL_BACK_TO_SNAPSHOT).live: always run the bundled helper. Fails if the toolchain is missing.snapshot: always read the committed snapshot. Fails if no snapshot path is configured.
When neither mode is viable, the build fails with RUSTDOC_NO_VIABLE_MODE and prints the exact rustup toolchain install and snapshot-config commands that fix it.
The sourcey-rustdoc binary
The bundled helper ships inside the npm package at node_modules/sourcey/dist/core/sourcey-rustdoc and compiles through Cargo on the first live-mode run. Cold compile takes 30 to 60 seconds; later invocations are near-instant. The same crate is published standalone as sourcey-rustdoc on crates.io for tools that drive snapshot generation from Rust.
sourcey-rustdoc --manifest <path> [options] [--output <file>|-]Key flags: --crate, --features, --all-features, --no-default-features, --include-private, --include-hidden, --target, --toolchain, --output (- writes to stdout), and --strict to exit non-zero on any error-level diagnostic.
Snapshot mode for CI on stable
CI hosts rarely carry a nightly toolchain. Generate a snapshot locally or in a dedicated job, commit it, and the docs build reads it on stable Rust, or on hosts with no Rust at all. A minimal generation script runs the bundled helper directly:
// scripts/snapshot-rustdoc.mjs
import { spawnSync } from "node:child_process";
const result = spawnSync(
"cargo",
[
"run", "--release", "--quiet",
"--manifest-path", "./node_modules/sourcey/dist/core/sourcey-rustdoc/Cargo.toml",
"--",
"--manifest", "./Cargo.toml",
"--toolchain", "nightly",
"--output", "./snapshots/rustdoc.json",
],
{ stdio: "inherit" },
);
process.exit(result.status ?? 1);Then point the tab at the snapshot:
source: rustdoc({
manifest: "../Cargo.toml",
snapshot: "./snapshots/rustdoc.json",
mode: "snapshot",
}),When you upgrade Sourcey, regenerate the snapshot with the same pinned nightly. If the rustdoc JSON format moves between versions, the build reports RUSTDOC_FORMAT_VERSION_MISMATCH with a remedy.
What gets rendered
- A workspace index with one card per crate, and a crate overview with one card per module
- One page per module, with constants, statics, functions, types, traits, macros, and re-exports rendered inline as sections
- Signatures with clickable cross-references; intra-doc links of the form
[`Foo`]resolve to internal pages, doc.rust-lang.org forstd/core/alloc, or docs.rs for external crates - Trait implementations collapsed behind a single disclosure, with auto and marker traits as a quiet list
- Every item flows into the search index,
llms.txt,llms-full.txt, andsitemap.xml
Doctests
Every code fence inside a /// or //! doc comment is extracted and rendered with:
- Hidden
#-prefixed lines stripped from the display copy, with a toggle to show them - Badges for
ignore,no_run,should_panic,compile_fail, andeditionYYYYfence attributes, each with a tooltip - A Run button that opens the example in the Rust Playground with the right edition
- A copy button
With doctestsIndex enabled (the default), a dedicated Doctests page aggregates every runnable example across the workspace, grouped by parent item and linked back to its source.
