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.htmlbecomes 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.