Zensical: Documentation Generator¶
Zensical is a fast static documentation site generator written in Rust and Python by
the creators of Material for MkDocs and mkdocstrings. It configures documentation via
typed zensical.toml files, replacing legacy mkdocs.yml setups.
What It Does¶
Zensical generates static technical documentation sites with sub-second live reloading.
It automates API documentation via mkdocstrings[python], client-side MathJax LaTeX
rendering, dynamic code execution through markdown-exec, and native Mermaid diagram
support.
It also compiles machine-readable site/llms.txt and site/llms-full.txt feeds,
allowing AI coding assistants to consume the library's entire API reference surface and
guides in a single, high-signal contextual payload.
Why It's in Zenith¶
Zenith chooses Zensical because it standardizes on TOML configuration (zensical.toml),
avoiding YAML sprawl and unifying configuration patterns with pyproject.toml.
With strict validation enabled (zensical build --strict), deployments fail
automatically if an internal link, anchor tag, footnote, or cross-reference is broken.
Designed for dual human and AI consumption, Zensical pairs modern responsive theming
with automated machine-readable feeds.
Integrated Plugins¶
Zenith enhances Zensical with specialized plugins configured under [project.plugins]:
| Plugin | Capability | Purpose in Zenith |
|---|---|---|
gh-admonitions |
GitHub Alert Callouts | Renders GitHub-flavored alert callouts (> [!NOTE], > [!TIP], > [!IMPORTANT], > [!WARNING], > [!CAUTION]) with styled border accents and icons. |
llmstxt |
AI Context Manifests | Compiles structured site/llms.txt and site/llms-full.txt feeds, allowing AI coding assistants to consume repository guides and API signatures in a single contextual payload. |
markdown-exec |
Dynamic Code Execution | Executes inline Python, Shell, Tree, and Markdown snippets (python exec="1", sh exec="1") during build, ensuring rendered tool configurations and directory trees reflect live repository files without manual copying. |
mkdocstrings[python] |
Automated API Documentation | Extracts and documents public Python functions, classes, type parameters, and protocols directly from source code docstrings via Griffe with NumPy style parsing. |
Markdown Extensions Suite¶
Zenith enables a suite of Python-Markdown and PyMdown Extensions under
[project.markdown_extensions] to support rich technical authoring:
| Extension Category | Extensions | Enabled Features |
|---|---|---|
| Callouts & Blocks | admonition, pymdownx.details |
Collapsible <details> blocks (??? note "Title"), inline notes, and standard warning callouts. |
| Code & Diagrams | pymdownx.superfences, pymdownx.highlight, pymdownx.inlinehilite |
Custom fences for interactive Mermaid diagrams, line numbers (anchor_linenums), syntax highlighting, and inline code formatting (#!python). |
| Math & Symbols | pymdownx.arithmatex, pymdownx.emoji, pymdownx.smartsymbols |
Client-side MathJax LaTeX formula rendering (\( ... \) and $$ ... $$), Twemoji SVG emojis (:octicons-code-24:), and typographic arrows. |
| Interactive UI | pymdownx.tabbed, pymdownx.tasklist, zensical.extensions.preview |
Multi-language tabbed code switchers (=== "Python"), interactive task checkboxes (- [x]), and instant link hover previews. |
| Typography & Structure | attr_list, def_list, footnotes, abbr, toc |
HTML attribute attaching ({: .grid .cards }), definition lists, footnotes ([^1]), glossary tooltips, and permalink anchors. |
| Content Reuse | pymdownx.snippets |
Transclusion of external files and code extracts directly into documentation (--8<-- "path/to/file"). |
Configuration in Zenith¶
Configured in zensical.toml at the project root:
# ==============================================================================
# Zensical Configuration (zensical.toml)
#
# Tool: Zensical (https://github.com/zensical/zensical)
# Purpose: Modern, fast static documentation site generator configured with TOML.
# Why it's in Zenith: Provides instant live-reloading documentation with native
# dark/light/system mode switching, Lucide icons, Mermaid diagrams, client-side
# MathJax integration for LaTeX math, markdown-exec for dynamic code execution,
# and mkdocstrings for automated Python API documentation generation.
# ==============================================================================
[project]
edit_uri = "edit/main/docs/"
repo_name = "{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}"
repo_url = "https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}"
site_author = "{{ cookiecutter.author_name }}"
site_description = "{{ cookiecutter.description }}"
site_name = "{{ cookiecutter.project_name }}"
site_url = "https://{{ cookiecutter.github_username }}.github.io/{{ cookiecutter.project_slug }}/"
nav = [
{ "Overview" = "index.md" },
{ "Getting Started" = "getting-started.md" },
{ "Reference" = "reference.md" },
{ "Architecture (ADRs)" = [
"adr/index.md",
{ "ADR-0001: Record Architecture Decisions" = "adr/0001-record-architecture-decisions.md" },
] },
{ "Changelog" = "changelog.md" },
]
extra_css = [
"stylesheets/palette.css",
"stylesheets/custom.css",
{% if cookiecutter.include_cli in [True, "yes", "true", "True", "1"] %}
"stylesheets/termynal.css",
{% endif %}
]
extra_javascript = [
"javascripts/mathjax.js",
"https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js",
{% if cookiecutter.include_cli in [True, "yes", "true", "True", "1"] %}
"javascripts/termynal.js",
{% endif %}
]
[project.validation]
invalid_links = true
invalid_link_anchors = true
shadowed_definitions = true
shadowed_footnotes = true
unresolved_footnotes = true
unresolved_references = true
unused_definitions = true
unused_footnotes = true
[project.theme]
features = [
"announce.dismiss",
"content.action.edit",
"content.action.view",
"content.code.annotate",
"content.code.copy",
"content.code.select",
"content.footnote.tooltips",
"content.tabs.link",
"content.tooltips",
"navigation.footer",
"navigation.indexes",
"navigation.instant",
"navigation.instant.prefetch",
"navigation.instant.preview",
"navigation.path",
"navigation.top",
"navigation.tracking",
"search.highlight",
"search.suggest",
"toc.follow",
]
language = "en"
logo = "assets/python-logo.svg"
[[project.theme.palette]]
media = "(prefers-color-scheme)"
toggle.icon = "lucide/sun-moon"
toggle.name = "Switch to light mode"
[[project.theme.palette]]
media = "(prefers-color-scheme: light)"
scheme = "default"
toggle.icon = "lucide/sun"
toggle.name = "Switch to dark mode"
[[project.theme.palette]]
media = "(prefers-color-scheme: dark)"
scheme = "slate"
toggle.icon = "lucide/moon"
toggle.name = "Switch to system preference"
[[project.extra.social]]
icon = "fontawesome/brands/github"
link = "https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}"
[project.markdown_extensions]
abbr = {}
admonition = {}
attr_list = {}
def_list = {}
footnotes = {}
md_in_html = {}
pymdownx.arithmatex.generic = true
pymdownx.betterem = {}
pymdownx.caret = {}
pymdownx.details = {}
pymdownx.emoji.emoji_generator = "zensical.extensions.emoji.to_svg"
pymdownx.emoji.emoji_index = "zensical.extensions.emoji.twemoji"
pymdownx.highlight.anchor_linenums = true
pymdownx.highlight.line_spans = "__span"
pymdownx.highlight.pygments_lang_class = true
pymdownx.inlinehilite = {}
pymdownx.keys = {}
pymdownx.magiclink = {}
pymdownx.mark = {}
pymdownx.smartsymbols = {}
pymdownx.snippets.check_paths = true
pymdownx.snippets.dedent_subsections = true
pymdownx.superfences.custom_fences = [
{ name = "mermaid", class = "mermaid", format = "pymdownx.superfences.fence_code_format" },
{ name = "tree", class = "tree", validator = "markdown_exec.validator", format = "markdown_exec.formatter" },
{ name = "markdown", class = "markdown", validator = "markdown_exec.validator", format = "markdown_exec.formatter" },
{ name = "md", class = "md", validator = "markdown_exec.validator", format = "markdown_exec.formatter" },
{ name = "python", class = "python", validator = "markdown_exec.validator", format = "markdown_exec.formatter" },
{ name = "bash", class = "bash", validator = "markdown_exec.validator", format = "markdown_exec.formatter" },
{ name = "sh", class = "sh", validator = "markdown_exec.validator", format = "markdown_exec.formatter" },
]
pymdownx.tabbed.alternate_style = true
pymdownx.tabbed.combine_header_slug = true
pymdownx.tasklist.custom_checkbox = true
pymdownx.tilde = {}
toc.permalink = true
zensical.extensions.preview.targets.include = ["*"]
[project.plugins.gh-admonitions]
[project.plugins.llmstxt]
full_output = "llms-full.txt"
[project.plugins.llmstxt.sections]
"Documentation" = [
"index.md",
"getting-started.md",
"reference.md",
"adr/index.md",
"adr/0001-record-architecture-decisions.md",
"changelog.md",
]
[project.plugins.markdown-exec]
[project.plugins.mkdocstrings]
default_handler = "python"
[project.plugins.mkdocstrings.handlers.python]
inventories = ["https://docs.python.org/3/objects.inv"]
paths = ["src"]
options.annotations_path = "brief"
options.backlinks = "tree"
options.docstring_options.ignore_init_summary = true
options.docstring_style = "numpy"
options.extensions = ["griffe_warnings_deprecated"]
options.line_length = 88
options.members_order = "source"
options.merge_init_into_class = true
options.parameter_headings = true
options.relative_crossrefs = true
options.scoped_crossrefs = true
options.separate_signature = true
options.show_bases = true
options.show_inheritance_diagram = true
options.show_root_heading = true
options.show_signature_annotations = true
options.show_signature_type_parameters = true
options.show_source = true
options.show_symbol_type_heading = true
options.show_symbol_type_toc = true
options.signature_crossrefs = true
options.summary = true
options.type_parameter_headings = true
options.unwrap_annotated = true
Key Invocations¶
uv run poe docs-serve # Start live-reloading dev server (localhost:8000)
uv run zensical serve -a 0.0.0.0:8080 # Bind to custom host address and port
uv run zensical serve -o # Open browser preview automatically
uv run poe docs-build # Strict production build into site/
Live Reloading Watchdog¶
zensical serve includes an integrated file watchdog:
- Instant Millisecond Rebuilds: Monitors
docs/,zensical.toml, assets, and stylesheets, updating pages in milliseconds as Markdown files are modified. - WebSocket Live Browser Sync: Automatically pushes updates to all open browser tabs without manual page refreshes.
- Agent Workflow Note: When developers run
uv run poe docs-servein a terminal window, AI agents do not need to execute rebuilds during editing turns because the watchdog reloads pages automatically.