Skip to content

About

A Rust static-site generator for Markdown doc repos — a from-scratch MkDocs replacement (reusable render engine + CLI)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

compositor

A Rust static-site generator for Markdown doc repos: point it at a directory of Markdown and get a themed, navigable static site. A drop-in replacement for MkDocs, with its render engine (render-core) also usable as a library.

Release Platform Rust License

Status

In use, 0.x. The rendering is stable; the CLI and compositor.toml surface may still change.

Two commands. build renders a docs tree to static HTML. serve is a live-reload dev server: it watches the tree, rebuilds in memory on change, and refreshes open browser tabs.

Edit in place. On a loopback serve, a topbar toggle flips the site into an in-place editor: click a paragraph, heading, list, table, or code block and edit it as rendered — changes autosave to the source .md and live-reload swaps the result back in. Only the blocks you touch are rewritten; admonitions, code, and frontmatter around them stay byte-for-byte. It's off on any non-loopback bind (serve --host 0.0.0.0) and never present in build output.

What you get, with no config: a Pico.css shell (top bar, light/dark toggle that persists, a collapsible tree-nav that opens to and centres on the current page, a per-page TOC with scroll-spy, a prev/next pager, a footer); GFM with syntect-highlighted code; MkDocs-style !!! admonitions and ??? collapsibles; MkDocs-style explicit heading ids (## Heading {#id}); [[wikilinks]] resolved by title, filename, alias, or path ([[Page#id]] deep-links to a heading); frontmatter title/aliases; .md→.html link rewriting; and non-Markdown assets copied through verbatim. Image paths, in ![](…) or raw <img src="…">, resolve against the page that references them; in the repo-root README.md, CLAUDE.md and AGENTS.md pages (below), against the repo root. Raw HTML renders as-is, as in MkDocs: build only content you trust.

A repo-root CLAUDE.md and/or AGENTS.md (when the docs dir is a subdir) gets its own top-level nav entry alongside Home (the repo-root README.md), both on by default. Set surface_claude_md = false and/or surface_agents_md = false in compositor.toml to hide either one. When both files are present and AGENTS.md's content is identical to CLAUDE.md's (a symlink or a copy), only the CLAUDE entry shows. Under the loopback editor these surfaced repo-root pages — Home (README.md), CLAUDE.md, and AGENTS.md — are themselves editable in place, the same as any page under the docs dir.

There is no site search.

As a library, the render-core crate turns a Markdown tree into an in-memory site model, and compositor's [lib] target exposes serve_handle/ServeHandle — an embedding API that runs a site on a loopback port, for host apps supervising many sites in one process, such as lector.

See CLAUDE.md for the full render surface and the known divergences from MkDocs.

Build & use

cargo build --release
./target/release/compositor build --dir path/to/docs-repo

That works anywhere Rust does — compositor is developed on macOS and runs on Linux.

Each release also ships a prebuilt x86_64-unknown-linux-gnu binary and its .sha256: a single binary with no runtime dependencies, for a Linux box with no Rust toolchain. Linux is the only prebuilt target — everywhere else, build from source with the two lines above.

A compositor.toml is optional:

Key Default What it does
site_name required when the file exists Site title in the top bar and <title>
docs_dir docs Docs tree to render, relative to --dir
out_dir site Where build writes the rendered site
exclude [] Docs-dir-relative path prefixes to skip (below)
surface_claude_md true Show a repo-root CLAUDE.md as a top-level nav entry
surface_agents_md true Show a repo-root AGENTS.md as a top-level nav entry

Without one, defaults are synthesized: site_name from the folder name, and the docs are taken from docs/ if that subdir exists, else the directory itself — so a bare folder of Markdown builds and serves with no config. In a compositor.toml, an unknown key or a syntax/type error fails the run.

Paths your repo's .gitignore ignores are skipped — in rendering, asset-copy, and serve's on-demand asset serving. Only the repo's own .gitignore files count (not the global ~/.config/git/ignore or .git/info/exclude), and outside a git repo nothing is skipped. exclude covers files git does track: a list of docs-dir-relative path prefixes (e.g. ["superpowers/"]) for a directory you keep in git but don't publish. Both apply. The rendered site lands in out_dir, which must not be, or contain, the project or docs dir; nothing under .git is ever published or served.

By default build is strict: an unresolvable internal link — or an image whose file isn't there — fails the build. Pass --lenient to publish anyway, rendering either as a 404. serve is always lenient.

For local editing, serve watches the docs tree and live-reloads the browser on every change:

./target/release/compositor serve --dir path/to/docs-repo --open

(--dir defaults to . and --host to 127.0.0.1; omit --port to let the OS pick a free port — the bound URL is printed on start — or pass --port to pin one. --open launches the default browser.)

Development

just build    # cargo build
just test     # cargo test
just gate     # fmt-check + clippy + test (the pre-merge gate)

Branch model and release process live in CLAUDE.md.

License

MIT — see LICENSE.

About

A Rust static-site generator for Markdown doc repos — a from-scratch MkDocs replacement (reusable render engine + CLI)

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages