This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
MD-book is a modern mdbook replacement written in Rust that generates HTML documentation from Markdown files. It supports multiple markdown formats (Markdown, GFM, MDX) with server-side syntax highlighting, live development server, and integrated search functionality via Pagefind.
# Basic build - converts markdown to HTML
cargo run -- -i input_dir -o output_dir
# Development mode with file watching
cargo run -- -i input_dir -o output_dir --watch
# Development with built-in server
cargo run -- -i input_dir -o output_dir --serve
# Full development mode (watch + serve on custom port)
cargo run -- -i input_dir -o output_dir --watch --serve --port 8080# Unit tests only
cargo test --lib --bins
# Run a single test
cargo test test_name
# Scope runs to specific crate/test
cargo test -p md_book test_extract_title
# Integration tests (requires features)
cargo test --test integration --features "tokio,search,syntax-highlighting"
# E2E tests
cargo test --test e2e --features "tokio,search,syntax-highlighting"
# All tests
cargo test --all-targets --features "tokio,search,syntax-highlighting"
# Run mdBook compatibility tests
cargo test --test mdbook_test_book
cargo test --test mdbook_compatibilitymake qa # Format check, clippy, unit tests
make dev-check # Complete development check
make ci-local # Simulate CI checks locally
cargo fmt # Format code
cargo clippy --all-targets --all-features -- -D warningsPagefind provides full-text search for generated documentation:
# Install pagefind CLI (required for search feature)
cargo install pagefind
# Manual indexing (automatically runs during build with search feature)
pagefind --site output_dir- main.rs: CLI entry point, orchestrates build/watch/serve via async tasks
- lib.rs: Library root with public API exports
- config.rs: Layered configuration using
twelf(env vars, TOML, JSON) - core.rs: Build logic - markdown processing, template rendering, navigation
- server.rs: Warp-based dev server with WebSocket live reload
- pagefind_service.rs: Search indexing via Pagefind CLI subprocess
- Load configuration (env → config file → book.toml → defaults)
- Initialize Tera templates (custom or embedded defaults)
- Copy static assets (CSS, JS, images, Web Components)
- Walk input directory, extract titles, build navigation structure
- Process each markdown file with syntax highlighting → render HTML
- Generate index.html (from index.md or card-based default)
- Run Pagefind search indexing (async, requires
pagefindCLI in PATH)
default = ["server", "watcher", "search", "syntax-highlighting"]
server = ["warp", "tokio/full", "futures", "futures-util"] # Dev server
watcher = ["notify", "tokio/full"] # File watching
search = ["pagefind", "tokio/rt", "tokio/macros"] # Pagefind search
syntax-highlighting = ["syntect"] # Code highlighting
wasm = ["wasm-bindgen"] # WASM supportBuild without optional features: cargo build --no-default-features
- CLI arguments
- Environment variables (MDBOOK_ prefix)
- Custom config file (--config flag)
- book.toml in current directory
- Default values
Templates in src/templates/ or custom directory via config:
page.html.tera- Individual page layoutindex.html.tera- Home pagesidebar.html.tera,header.html.tera,footer.html.tera- Layout partialscomponents/- Web Components (doc-toc, search-modal, simple-block)
- markdown: Multi-format parsing (standard, GFM, MDX)
- tera: Template engine
- syntect: Server-side syntax highlighting
- pagefind: Full-text search engine (requires CLI:
cargo install pagefind) - warp: HTTP server with WebSocket
- notify: File system watching
- twelf: Configuration management
- jiff: Date/time operations (use instead of chrono)
The codebase uses extensive conditional compilation:
#[cfg(feature = "server")]
pub mod server;
#[cfg(feature = "tokio")]
pub async fn build(...) -> Result<()> { ... }
#[cfg(not(feature = "tokio"))]
pub fn build(...) -> Result<()> { ... }Uses anyhow::Result for application errors and thiserror for library error types (see PagefindError).
let config = config::load_config(args.config.as_deref())?;- Keep fast unit tests inline with
mod tests {}; put multi-crate checks intests/ortest_*.sh - Scope runs with
cargo test -p md_book test_name; add regression coverage for new failure modes - Write tests using
#[tokio::test]for async code - Never use mocks - use real implementations or test doubles
- Run
make ci-localbefore pushing to verify CI will pass
- Profile first (
cargo bench,cargo flamegraph,perf) and land only measured wins - Borrow ripgrep tactics: reuse buffers with
with_capacity, favor iterators, reach formemchr/SIMD, and hoist allocations out of loops - Apply inline directives sparingly—mark tiny wrappers
#[inline], keep cold errors#[cold], and guard rayon-style parallel loops with#[inline(never)] - Prefer zero-copy types (
&[u8],bstr) and parallelize CPU-bound work withrayon, feature-gated for graceful fallback - Benchmark file:
benches/pagefind_bench.rs
- Use Conventional Commit prefixes (
fix:,feat:,refactor:) and keep changes scoped - Ensure commits pass
cargo fmt,cargo clippy, requiredcargo test, and desktop checks - PRs should explain motivation, link issues, list manual verification commands, and attach UI screenshots or logs when behavior shifts
- Keep secrets in 1Password or
.env(never commit.env) - Use
scripts/helpers to bootstrap integrations (e.g.,scripts/deploy.sh,scripts/setup-cloudflare.sh) - Wrap optional features with graceful fallbacks for network failures
- See
.env.examplefor required environment variables template
See DEPLOYMENT.md for comprehensive deployment documentation including:
- Cloudflare Pages setup (primary deployment target)
- Netlify configuration
- GitHub Actions workflows
- 1Password secret management integration
Quick deploy:
./scripts/deploy.sh production # Cloudflare Pages
netlify deploy --prod --dir=dist # NetlifyAlways use jiff instead of chrono for date/time operations.