Skip to content

Tooling decision: why Zensical

This page records why this site is built with Zensical and not one of the alternatives. It is a decision record, not a tutorial: the landscape as of 2026-07-19, the choice, the trade-offs we accepted, and the exit ramp.

The decision

Zensical 0.0.51, installed from PyPI (pip install zensical), released 2026-07-17, MIT-licensed, written by the team behind Material for MkDocs.

The site lives at docs/guide/ in the repo. The config is a single TOML file, docs/guide/zensical.tomlsite_name = "NPS Guide" (docs/guide/zensical.toml:14), navigation declared explicitly (docs/guide/zensical.toml:47-69), mermaid fenced through pymdownx.superfences (docs/guide/zensical.toml:359-362). Zensical 0.0.51 is the version installed in the working environment (pip show zensical).

On 2026-07-19 the standalone docs/codebase-map/ site was unified into this site as the Codebase section; its hand-rolled viewer (site/, serve.sh, hash routing, PAGES array) and Docker setup were retired.

Commands:

pip install zensical                                  # one-time
zensical serve -f docs/guide/zensical.toml             # live preview while writing
zensical build -f docs/guide/zensical.toml             # static site into docs/guide/site/

The landscape (verified via web, 2026-07-19)

Tool Status on 2026-07-19 Why not
Material for MkDocs 9.7.7 Released 2026-07-17; project in maintenance mode since 9.7.0, the final feature release (announced 2025-11-11) — critical fixes only, promised for at least 12 months (until roughly Nov 2026) No future feature development; building a new site on a sunset theme borrows a migration
MkDocs 1.x core Unmaintained — 18+ months without a release The engine under Material is itself stalled
MkDocs 2.0 (encode fork) Pre-release; removes the plugin system; repo inactive since 2026-02-19 Community confidence low; plugin removal breaks the ecosystem we would rely on
DocFX Actively maintained, .NET-native Heavier for a prose-and-mermaid site; weaker mermaid and theme story than the Material lineage
VitePress / Docusaurus Actively maintained Node toolchain — the repo has no node dependencies in use; adopting either adds a second language's dependency management for docs alone
mdBook Actively maintained Rust toolchain — same objection as node; theme and admonition story is thinner

Why Zensical

  1. Standard tool, not a custom script. Anyone who has used Material for MkDocs already knows the mental model: one config file, docs/ of markdown, serve and build. The config in this repo is proof — the nav (docs/guide/zensical.toml:47-69), the theme palette (docs/guide/zensical.toml:309-318), and the markdown-extension tables (docs/guide/zensical.toml:339-368) read exactly like an mkdocs.yml, in TOML form.
  2. Python, like the existing docs workflow. The repo already uses Python for tooling (lefthook.yml hooks call python3; scripts/_smoke_scan.py); pip install zensical adds no new runtime and no new language's package manager to the docs workflow.
  3. One coherent theme for both apps. The site covers Slicer, Simulator, and what they share (see the site index). Zensical ships the Material look — palette toggle, navigation sections, admonitions — out of the box, so the pages could be written, not themed.
  4. Native mermaid. Every interaction page on this site uses mermaid diagrams. Zensical renders them through pymdownx.superfences custom fences — configured at docs/guide/zensical.toml:359-362 — with no JavaScript plugin to maintain.

Trade-offs, stated honestly

  • First load needs network. Mermaid (unpkg.com/mermaid@11) and fonts (Google Fonts) load from CDNs on first view; browser cache covers you afterwards — the same trade-off the retired codebase-map viewer's serve.sh documented. Search works offline via [project.plugins.offline] in zensical.toml. Zensical 0.0.x has no clean mermaid/font vendoring hook yet; if full offline becomes a requirement, the retired codebase-map Docker-vendoring pattern (still in git history) is the precedent to copy.
  • Pre-1.0. Zensical is at 0.0.x (0.0.51 as of this writing). The config schema may shift between minor releases; the TOML we wrote against 0.0.51 is not guaranteed to be valid forever. Pin the version when installing for CI-like reproducibility: pip install zensical==0.0.51.
  • Young ecosystem. MkDocs plugins do not run on Zensical. This site needs none — markdown, tables, mermaid, and admonitions cover it — but a future need for a plugin-only feature would mean waiting or working around it.
  • Exit ramp. All content on this site is plain markdown plus standard mermaid fenced blocks. Nothing is Zensical-specific except zensical.toml itself. If Zensical stalls the way MkDocs did, the docs/ tree ports to any static site generator in an afternoon — the custom_fences mermaid mapping is the only non-obvious line to carry over.

INFERENCE

The "ports in an afternoon" estimate is INFERENCE — it follows from the content being plain markdown, but no port has actually been performed or timed.

The Zensical starter template ships a .github/workflows deploy workflow. It was deleted, because the repo itself removed GitHub Actions: commit 705b28e chore(ci): remove GitHub Actions; lefthook is the only gate. There is no .github/ directory in the repo today; the only pre-push gate is lefthook.yml at the repo root. This site is therefore built locally with zensical build -f docs/guide/zensical.toml; there is no CI deploy to document.

Hosting

This site is hosted on Cloudflare Pages (project nps-guide) and is live at https://docs.nonplanarslicer.com/ (custom domain; the https://nps-guide.pages.dev fallback also works). site_url in docs/guide/zensical.toml points at the canonical URL so the built sitemap is non-empty.

Deploys are local and hook-driven: there is no CI, no GitHub Actions workflow, and no dashboard git integration. Publishing happens two ways, both from a developer machine:

  • Automatic on push — the lefthook pre-push command docs-deploy fires only when the pushed commits touch docs/guide/** or scripts/deploy-docs.sh, and runs the deploy script. It is fail-closed: a failed build or unauthenticated wrangler blocks the push. This hook is the entire CD pipeline.
  • Manual — run from anywhere in the repo:
bash scripts/deploy-docs.sh

The script checks wrangler whoami, runs zensical build --clean (which must print "No issues found"), then deploys docs/guide/site/ with wrangler pages deploy site --project-name nps-guide --branch main.

Prerequisite: wrangler authenticated against the Cloudflare account (npx wrangler login once; account details are recorded in bead nps-rd5.5.2). Local preview while writing is unchanged:

zensical serve -f docs/guide/zensical.toml

See also