Grimoire
Build a documentation website - and a printable PDF - from a directory of Markdown files. What mdBook and MkDocs do, written in Jennifer.
Point it at a directory of Markdown. If that directory holds a SUMMARY.md it is used as the book outline, in the mdBook shape; if it does not, the outline is derived from the directory tree, the way MkDocs does. The output is a self-contained static site - themed, searchable, with a colour-mode selector - plus, on request, the whole book as one paginated PDF.
./grimoire init my-book # scaffold a book
./grimoire build # build the site
./grimoire build --pdf # site plus the printable book
./grimoire pdf # the printable book on its own
./grimoire serve # build, then preview on :8080
./grimoire themes # list the built-in themesgrimoire is a Jennifer script with a shebang; the program itself is src/main.j. It runs from any working directory and through any symlink, so either put the checkout on your PATH or link the launcher into a directory already on it, and the leading ./ goes away:
ln -s "$PWD/grimoire" ~/.local/bin/grimoireA built site is a directory of files that works served from a web root, served from a subdirectory, or opened straight off the disk over file:// - search included. Nothing is fetched from anywhere unless you opt in, and the only setting that reaches off the machine at all is [highlightjs], which is off by default.
Read this manual as a single PDF. Every page in one paginated file, with a clickable outline in your reader's bookmark panel and
page/totalin the footer - handy for reading offline. It is built from these same pages on every build, so it never drifts from the site.
What it does
- Two outline styles.
SUMMARY.mdwith part headings, nested entries, prefix and suffix chapters, drafts, and separators; or noSUMMARY.mdat all, in which case the directory tree becomes the outline. - Anchors that match mdBook and GitHub exactly, so hand-written cross-references survive a migration.
### REPL (cmd/jennifer/repl.go)anchors at#repl-cmdjenniferreplgo, not#repl-cmd-jennifer-repl-go. - Links rewritten:
[x](guide/syntax.md#anchor)becomesguide/syntax.html#anchor; a directoryREADME.mdfolds onto itsindex.html. - Client-side search over per-section records, so a hit lands on the paragraph rather than the top of a long chapter. Opens with
/orCtrl-K, arrow keys to move,Enterto open. No search library: the index and the scorer are both Grimoire's own, and the index loads as a script rather than afetchso it works overfile://. - Ten themes, each with a light and a dark palette.
- A mandatory dark mode. Every theme ships both palettes; the selector in the top bar offers light, dark, and follow-the-system, and the choice is stamped on the document before the first paint, so there is no white flash on navigation.
- Syntax highlighting in two layers.
[highlight]alone highlights Jennifer while the site is built - no CDN, no JavaScript, nothing to load, and it works with scripting off.[highlightjs]additionally pulls highlight.js from a configurable CDN for the other languages. Both are off by default, and the second does nothing without the first. - A logo beside the title: an SVG is inlined, so it inherits the colour mode and costs no extra request.
- A printable book: every chapter in one PDF, with a cover page, chapters starting on fresh pages, a nested bookmark outline, and document metadata. It wears the book's theme too - heading bars, table headers, code panels, and the tint and rule on a blockquote all come from the theme's light palette.
- Chapters render in parallel, one task per CPU, with the work split longest-chapter-first. With
--pdf, the PDF is laid out alongside the site rather than after it. - Deterministic output. The same input produces byte-identical files - including the search index, whose order does not depend on how the work was split across jobs.
Where to go next
| Commands | every subcommand and flag |
| Configuration | grimoire.toml, key by key |
| Themes | the ten themes, with screenshots, and how to write one |
| Docker | running from the official image, and the Grimoire image |
| Internals | the source layout, and what Grimoire does to the Markdown |
| Performance | where the time goes, and why it scales the way it does |
Requirements
Jennifer 0.25.0 or newer.
build, pdf, init, and themes run on both the default binary and jennifer-tiny; serve needs the default binary, since jennifer-tiny stubs httpd. To pick the embeddable interpreter, invoke it directly rather than through the shebang:
jennifer-tiny run ./grimoire buildLicense
LGPL-3.0-only. Copyright (C) 2026 mplx <jennifer@mplx.dev>.