Use Comma with marimo
marimo fixed the notebook half of the problem: reactive execution, no
hidden state, notebooks stored as plain Python files that diff cleanly in
git. And it ships an honest export story — marimo export html snapshots
the notebook, outputs included, into an HTML file.
What it doesn't ship is the step after: the analysis is done, the export
exists, and now a PM, a data lead, and two engineers need to read it and
tell you what's wrong with it. Git diffs of the .py file review the
code. Nobody reviews the findings in a diff.
Comma is that step. Publish the export, share one link, and feedback arrives anchored to the exact output it's about.
The pipeline
1. Export the notebook
marimo export html retention_analysis.py -o retention.html
This snapshots the notebook as it last ran — markdown, code, rendered
outputs — into a single HTML document. That's the right artifact for
review: the run you got, frozen, not a live re-execution that might
differ. (Skip the html-wasm export here; it builds a multi-file site
for static hosting, and Comma takes one document.)
2. Publish it to Comma
The create endpoint accepts JSON with a required html field and
optional title and description:
jq -Rs '{title: "Retention analysis — June", html: .}' retention.html |
curl -s -X POST https://commareports.com/api/v1/reports \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @-
The response carries the link to share:
{
"id": "b27e…",
"title": "Retention analysis — June",
"created_at": "2026-06-10T08:00:00Z",
"edit_url": "/r/b27e…",
"share_url": "/p/b27e…"
}
Reports default to public-with-link, view-only. Add
"public_permission": "comment" so anyone with the link can comment, or
"visibility": "private" to restrict it to people you invite. Tokens are
minted under Settings → API tokens, scoped and revocable. HTML up to
5 MB.
3. Review like a document
Reviewers open the link in a browser — no marimo install, no environment setup, no repo access. They highlight a sentence in your markdown commentary or a cell in a results table and pin a comment to it, Google-Docs style. Threads, replies, resolution. Commenting is free on every plan; only creators pay, and only for scheduling and team features.
4. Re-run, republish, same link
When the comments come back — "cell 4's join is dropping nulls," "rerun with the May cohort included" — fix the notebook, export, and PATCH:
jq -Rs '{html: .}' retention.html |
curl -s -X PATCH "https://commareports.com/api/v1/reports/$REPORT_ID" \
-H "Authorization: Bearer $COMMA_API_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @-
Comma appends a revision under the same share URL and keeps the comment threads attached, so the conversation and the artifact stay in one place across runs.
What renders, honestly
Comma renders the export untouched in an opaque-origin sandbox — no
reformatting, no restyling. One deliberate exception: the API strips
<script> tags before storage, as defense-in-depth on an endpoint that
accepts arbitrary HTML. For a marimo export that means markdown, code,
tables, and static figures (matplotlib SVG/PNG, rendered DataFrames)
survive faithfully, while script-driven interactivity — altair/plotly
tooltips, marimo UI elements — renders statically or not at all.
For review that's usually the right trade: a comment can anchor to a rendered chart; it can't anchor to a hover state. Keep the interactive notebook for exploration and publish the snapshot for review.
With an agent in the loop
If the notebook is run by Claude Code or Cursor, skip the curl. Comma's
MCP server exposes create_report, update_report, list_comments, and
reply_to_comment as typed tools under the same comma_sk_… token. The
agent exports the notebook, publishes the HTML, and — on its next run —
reads the anchored comments and addresses them before republishing. The
Claude Code plugin installs in one line.
To make the whole thing recur, either run the export + PATCH from your own cron (works on Free), or use Comma routines — hosted scheduling that re-runs a skill and republishes, daily on Pro ($9/month) and hourly on Team.
Try it
Export a notebook you've already run and publish it. The difference shows up in the first comment: it lands on the row of the table it's about, instead of in a Slack thread describing where to look.
Related
- Use Comma with Quarto — the document-renderer pipeline
- Datapane alternative — the publish-and-share gap
- Comment on HTML — how anchored comments work