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.0.tar.gz (134.7 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.0-py3-none-any.whl (68.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: marimo_book-0.1.0.tar.gz
  • Upload date:
  • Size: 134.7 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.0.tar.gz
Algorithm Hash digest
SHA256 416e47c0de41ded647bbe4d107ff952b58ec8a7b0c8ec37e80699d61b1f95b55
MD5 c7ad0a704bf5044fadfa9ff98ce7e020
BLAKE2b-256 60a47452d4180a1ae5361aa4c2068afd3c71e5b13d9b4b31430f4382be3043af

See more details on using hashes here.

Provenance

The following attestation bundles were made for marimo_book-0.1.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: marimo_book-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 68.4 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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b07edd5968b8d1e5376650f2afa5b6e913ee32ef6a315574a42b80d3e4851278
MD5 b5cce4fb36221016449e5d67cd89b8ad
BLAKE2b-256 6e62e1ef3515d2c6efe86ed6815b5aaca4a104ca1d56d3e40d49565a32ca21ea

See more details on using hashes here.

Provenance

The following attestation bundles were made for marimo_book-0.1.0-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