Share a marimo notebook

marimo notebooks are Python files, which makes them wonderful in git and awkward in a review. Sending analysis.py to a stakeholder is sending them homework. What they want is the output.

marimo gives you two exports, and they answer different questions:

# a frozen snapshot of the last run — a report
marimo export html notebook.py -o notebook.html

# a runnable notebook that boots Pyodide in the browser — an app
marimo export html-wasm notebook.py -o dist/ --mode run

Both leave you holding something that is hard to hand over. The static export is one big file that lands in a Downloads folder and rots. The wasm export is a directory that cannot be opened by double-clicking — module fetches are blocked on file://, which is why marimo's docs tell you to serve it.

Publish the static export

Drag notebook.html into the app, or PATCH it:

marimo export html notebook.py -o notebook.html

curl -fsS -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
  -H "Authorization: Bearer $COMMA_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile html notebook.html \
        --arg title "Cohort analysis — $(date +%F)" '{title: $title, html: $html}')"

Publish the wasm export

Drag the whole dist/ folder (or a zip of it):

  • index.html becomes the report body.
  • The Pyodide bundle, wheels and static assets upload alongside it, with their relative references rewritten to the uploaded copies — the step file:// can't do.
  • Scripts run inside a sandboxed iframe, so sliders, dropdowns and the reactive re-execution all work for the reader.

Keep an eye on size here: assets are capped at 25 MB per file and 250 MB total, and a wasm export that ships scientific wheels is not small. If it doesn't fit, publish the static export and link the repo.

Why a URL beats a file

The notebook is the argument; the comments are the review.

  • Anchored threads on the cell output someone is questioning — see commenting on HTML.
  • Revisions — PATCH one report id per notebook and every run is kept, so "this number changed" is a diff, not a memory.
  • Access per report — private, team, domain-gated, or named reviewers. See the sharing model.

Re-run it on a schedule

If the notebook reads live data, export it from a routine and PATCH the same id. The URL you shared once keeps showing current output.

Limits

  • Entry HTML: 5 MB. Assets: 25 MB per file, 250 MB and 500 files total.
  • 60 requests/minute per token.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a notebook →

Related