Documentation and Examples
A battery pack's documentation shows up in two places: on crates.io (from README.md) and on docs.rs (from the auto-generated lib docs). The doc generation system lets you write prose naturally while getting an auto-generated crate catalog for free.
How it works
The documentation pipeline has three pieces:
- README.md — your hand-written prose, displayed on crates.io
- docs.handlebars.md — a template that controls what appears on docs.rs
- build.rs — renders the template into
docs.mdat build time
The generated docs.md is included by lib.rs:
#![allow(unused)] #![doc = include_str!(concat!(env!("OUT_DIR"), "/docs.md"))] fn main() { }
Writing your README
Write a normal README.md. It should explain what your battery pack provides, when to use which crates, and any guidance that helps users get started.
For example, error-battery-pack's README might say:
# error-battery-pack
Error handling done well — anyhow for apps, thiserror for libraries.
## When to use what
- **anyhow** — Use in application code where you want easy error
propagation with context. Great for `main()`, CLI handlers,
and integration tests.
- **thiserror** — Use in library code where you want to define
structured error types that callers can match on.
The handlebars template
The docs.handlebars.md file is a Handlebars template
that controls what goes into the docs.rs documentation. The default template
shipped by cargo bp new looks like:
{{readme}}
{{crate-table}}
{{readme}}— includes the contents of your README.md{{crate-table}}— renders an auto-generated table of all curated crates
The crate table
The {{crate-table}} helper generates a table listing each crate in
the battery pack with its version, description, and a link to crates.io.
The descriptions are pulled automatically from crate metadata
(via cargo metadata), so you don't have to maintain them by hand.
When the battery-pack crate updates, the table's formatting improves
automatically for all battery packs that use {{crate-table}}.
Custom templates
If you want full control, replace {{crate-table}} with your own
Handlebars markup. The same metadata is available in structured form:
{{readme}}
## Curated Crates
| Crate | Version | Description |
|-------|---------|-------------|
{{#each crates}}
| [{{name}}](https://crates.io/crates/{{name}}) | {{version}} | {{description}} |
{{/each}}
{{#if features}}
## Features
{{#each features}}
### `{{name}}`
{{#each crates}}
- {{this}}
{{/each}}
{{/each}}
{{/if}}
The available template variables include:
crates— array of{ name, version, description, features, dep_kind }features— array of{ name, crates }from[features]readme— the contents of README.mdpackage—{ name, version, description, repository }
Writing examples
Examples are standard Cargo examples in the examples/ directory.
They serve two purposes: showing users how to use the curated crates together,
and appearing in the battery pack's listing (in the TUI and cargo bp show).
Good examples:
- Are self-contained and runnable
- Show the crates working together (not just one crate in isolation)
- Cover common use cases for the battery pack's domain
// examples/basic.rs use anyhow::{Context, Result}; use thiserror::Error; #[derive(Error, Debug)] #[error("config error: {0}")] struct ConfigError(String); fn main() -> Result<()> { let path = "config.toml"; let _content = std::fs::read_to_string(path) .context("reading config file")?; Ok(()) }
Examples listed in the TUI link to the source on GitHub (when a repository URL is provided in Cargo.toml).