Skip to main content

Build clean, searchable static books from marimo notebooks and markdown

Project description

marimo-book

PyPI version Python versions CI License: MIT Docs

Build clean, searchable static books from marimo notebooks and Markdown files.

marimo-book is a Jupyter-Book-style static site generator built specifically for marimo .py notebooks. It produces polished multi-page sites with:

  • Collapsible sidebar and chapter-aware navigation
  • Fast full-text search across prose and baked cell outputs
  • Admonitions, math, figures, tables with Material for MkDocs defaults
  • Anywidgets that render statically (no marimo kernel required)
  • Launch buttons per-chapter for molab / GitHub / download .py
  • Dark-mode toggle that persists across navigation
  • GitHub Pages deploy workflow scaffolded in for you

Status

Alpha (v0.1.0a1, April 2026). marimo-book is usable end-to-end and is actively building a real course site (dartbrains), but the book.yml schema may still change before v1.0. Pin the exact version in your project until we signal stability.

Install

pip install marimo-book

Requires Python 3.11+.

Quickstart

# Scaffold a new book
marimo-book new mybook
cd mybook

# Live-reload dev server (http://127.0.0.1:8000/)
marimo-book serve
#
# Note on macOS: mkdocs's browser auto-reload is flaky on some
# macOS setups. If the browser doesn't refresh automatically after a
# save, hard-refresh (Cmd-R). The preprocessor + rebuild are
# reliable; only the browser push is affected.

# One-shot static build (emits ./_site/)
marimo-book build

# Validate book.yml + content without building
marimo-book check

# Remove build artifacts
marimo-book clean

Deploy to GitHub Pages by pushing the scaffolded workflow (.github/workflows/deploy.yml) to main on a repo with Pages enabled.

How it works

Two-stage build, by design:

content/*.md + *.py + book.yml
  → marimo-book preprocessor
  → _site_src/docs/*.md  +  _site_src/mkdocs.yml
  → mkdocs build (Material theme)
  → _site/
  1. The preprocessor reads book.yml and walks the TOC. For each .md it applies small content transforms (../images/ path fixups, .ipynb.md cross-ref rewriting). For each marimo .py it runs marimo export ipynb --include-outputs and converts the cells into Markdown + inline HTML, translating marimo custom elements (<marimo-callout-output>, <marimo-anywidget>) into their static analogs.
  2. Material for MkDocs (or later, zensical — which reuses mkdocs.yml verbatim) builds the final HTML.

The preprocessor is not a mkdocs plugin — it emits plain Markdown + inline HTML. This keeps the shell swappable: Material today, zensical tomorrow, or a hand-rolled Jinja shell as a last-resort fallback.

book.yml

title: My Book
description: A static site from marimo notebooks + Markdown.
authors:
  - name: Your Name
    orcid: 0000-0000-0000-0000       # optional
repo: https://github.com/you/yourbook
branch: main

theme:
  palette:
    primary: "#1976D2"
    accent:  "#FF9800"

launch_buttons:
  molab: true          # "Open in molab" button on every .py page
  github: true         # "View on GitHub"
  download: true       # "Download .py source"

# Per-widget default state for anywidgets whose JS needs initial model
# values to render on first paint. Literal kwargs from the cell override
# these; unset keys fall through to the widget's own JS defaults.
widget_defaults:
  CompassWidget:
    b0: 3.0

toc:
  - file: content/intro.md
  - section: Part I
    children:
      - file: content/chapter1.py
      - file: content/chapter2.py
  - section: Part II
    children:
      - file: content/chapter3.py
      - url: https://example.org/external-reading
        title: External Reading

See marimo-book new for a full starter template with comments on every field.

What's supported in v0.1

Material for MkDocs handles natively (free):

  • Full-text search, dark mode, keyboard shortcuts, code-copy buttons, collapsible sidebar, breadcrumbs, next/previous navigation, admonitions (!!! note / !!! tip / !!! warning / etc.), math, responsive theme, edit-this-page link, analytics, top-of-page banner

Preprocessor adds:

  • book.ymlmkdocs.yml generation (TOC, theme, palette, fonts, extensions, plugins all derived)
  • .py → rendered Markdown + inlined anywidget / callout / image outputs
  • Static rehydration of anywidgets via a small JS shim (marimo_book.js, loaded via extra_javascript)
  • Launch-button row per chapter (molab / GitHub / download)
  • [text](Foo.ipynb)[text](Foo.md) cross-ref rewrite when Foo.md exists in the staged tree
  • ../images/images/ relative-path fixup when content/ is flattened
  • First-code-cell hiding (the setup-imports convention) — opt out via defaults.hide_first_code_cell: false

Notebook dependencies

Notebooks need their imports satisfied at build time (marimo re-executes every cell to capture outputs). marimo-book supports two modes; pick in book.yml:

dependencies:
  mode: env       # default — reuse the active venv
  # mode: sandbox # per-notebook PEP 723 isolation via uv

env mode (default). Whatever Python env runs marimo-book provides the deps. The typical consumer has a pyproject.toml at the book root listing notebook dependencies (numpy, pandas, your domain package, etc.), installs with pip install -e . or uv pip install -e ., and runs marimo-book from that env. Fast, straightforward, good when all notebooks share the same stack.

sandbox mode. Passes --sandbox to marimo export. Each notebook must declare its own deps via PEP 723 inline script metadata:

# /// script
# dependencies = [
#     "marimo>=0.23",
#     "numpy>=2.0",
#     "pandas>=2.0",
# ]
# ///

import marimo
# ...

At build time, marimo uses uv run --isolated to provision a fresh env per notebook. ~5–10 s on first run, cached after. Notebooks become portable — copy a .py into any repo with uv installed and it just works. The book root doesn't need a pyproject.toml.

Override per invocation:

marimo-book build --sandbox    # force sandbox regardless of book.yml
marimo-book build --no-sandbox # force env mode
marimo-book serve --sandbox    # slower iteration, but reproducible

Use env for local dev loops and sandbox on CI where reproducibility matters more than rebuild speed.

Broken-link checking

mkdocs build --strict (use marimo-book build --strict) already fails on broken in-tree links and anchors. For external URLs and image src attributes, opt into the htmlproofer plugin:

# book.yml
check_external_links: true
pip install 'marimo-book[linkcheck]'
marimo-book build --strict

External link checking hits the live web, so it's slow (~1–3 s per link). Keep it off on CI unless you're cutting a release.

Not in v0.1 (planned):

  • WASM / hybrid render modes — static only in v0.1; architecture already supports the branch
  • Dependency-graph-aware incremental build cache
  • BibTeX citations with hover-cards (no book needs them yet)
  • PDF / EPUB export — opt-in via mkdocs-with-pdf if needed

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

marimo_book-0.1.5.tar.gz (159.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

marimo_book-0.1.5-py3-none-any.whl (80.2 kB view details)

Uploaded Python 3

File details

Details for the file marimo_book-0.1.5.tar.gz.

File metadata

  • Download URL: marimo_book-0.1.5.tar.gz
  • Upload date:
  • Size: 159.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for marimo_book-0.1.5.tar.gz
Algorithm Hash digest
SHA256 074de9978e9d7d5d819c3e12b29a2b0bdf260c9be666e1d6d6b19c0e686dfab1
MD5 e8c24ec73a06e9a149ae49b916c9e006
BLAKE2b-256 fb712eaad7b110bb6d2f8a058a94665a29641f2b31aa613dea61d8bc8734b757

See more details on using hashes here.

Provenance

The following attestation bundles were made for marimo_book-0.1.5.tar.gz:

Publisher: publish.yml on ljchang/marimo-book

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file marimo_book-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: marimo_book-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 80.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for marimo_book-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 858cf692651a2ef446310d23bc1bcdea50e539fcdfcd0a25375032217a83f552
MD5 a5ba1ee9ddc87bfe0a3d444f2aeca3a0
BLAKE2b-256 d7f9aa013b2488176a2662b07e540b90471dcabd2f22ce8188d8b3b5910b56a7

See more details on using hashes here.

Provenance

The following attestation bundles were made for marimo_book-0.1.5-py3-none-any.whl:

Publisher: publish.yml on ljchang/marimo-book

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page