Skip to content

Notebooks

Experimental feature

This part of the site experiments with rendering notebooks in a static website to avoid costly backend services. This way the project outputs can outlive the project funding, but interactivity is far more limited than, say, a streamlit app.

We are using marimo notebooks and their export functionality.

Exporting marimo notebooks

marimo notebooks (the *.mo.py files) can be exported to two web-friendly formats:

  • HTML — a static, self-contained snapshot of the notebook and its outputs.
  • HTML+WASM — a self-contained page that re-runs the Python in the browser via Pyodide, so the notebook stays interactive with no server.

All commands assume the project venv, so prefix with uv run.

Static HTML

uv run marimo export html h3-analysis.mo.py -o ../site/docs/notebooks/h3-analysis.html

Renders the code and the currently-embedded outputs to a single file. It is a snapshot: nothing re-executes, and UI elements (sliders, dropdowns, etc.) are inert.

Useful flags:

  • --no-include-code — publish outputs only, hiding the source.
  • --watch — regenerate on every save while you iterate.

Interactive HTML+WASM

uv run marimo export html-wasm h3-analysis.mo.py -o out/ --mode run

Produces a directory containing an HTML file (plus assets) that boots a Python runtime in the browser. --mode run gives a read-only app; --mode edit makes cells editable.

Useful flags:

  • --show-code — reveal source in run mode (hidden by default).
  • --execute — run the notebook at export time and embed the outputs as a preview, so the page shows results immediately instead of a blank state while the runtime warms up.
  • --include-cloudflare — also emit index.js / wrangler.jsonc for Cloudflare deployment.

Caveats

Applies to WASM exports

  • Must be served over HTTP. Opening the file via file:// will not work — use python -m http.server, GitHub Pages, Cloudflare, etc.
  • Pyodide package limits. The notebook runs against Pyodide's package set, which is "most but not all" of PyPI. Packages with heavy native/C dependencies may be missing or slow to load. For this repo in particular, duckdb, its spatial/h3/azure extensions, geopandas, and the local safer-streets-core package are unlikely to work unmodified under WASM. Notebooks that lean on DuckDB + spatial extensions are effectively not WASM-portable today.
  • Cold-start cost. The runtime and every package are downloaded and initialised in the browser on first load, which can be several seconds to tens of seconds.
  • No data access. Anything that reads from Azure, a local file, or another networked source will fail unless the data is public and CORS-accessible from the browser.

Applies to static HTML

  • It is a frozen snapshot — outputs are whatever was last computed and embedded, and interactivity is lost. Re-export after re-running the notebook to refresh it.

Which to use

  • Sharing results / archiving → static HTML.
  • Letting someone poke at a self-contained, lightweight notebook → HTML+WASM.
  • Notebooks that depend on DuckDB, spatial extensions, or private data → neither travels well; share the static HTML for the writeup and point people at uv sync to run it for real.