skills/marimo/SKILL.md
Use when working with marimo notebooks — creating, editing, debugging, converting from Jupyter, or pairing with a running marimo server.
npx skillsauth add edwinhu/workflows marimoInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Marimo is a reactive Python notebook where cells form a DAG and auto-execute on dependency changes. Notebooks are stored as pure .py files.
Only edit code INSIDE @app.cell function bodies. This is not negotiable.
NEVER modify:
@app.cell)def _(deps):)ALWAYS verify:
return var,Before claiming ANY marimo notebook works:
marimo check notebook.pymarimo export ipynb notebook.py -o __marimo__/notebook.ipynb --include-outputsThis is not negotiable. Skipping execution and output inspection is NOT HELPFUL — the user gets a notebook that fails when they open it.
marimo check validates syntax and structure only — it never executes cells. Claiming a notebook works because check passed is an unverified claim presented as fact.return var as returning the bare value, which breaks unpacking — single returns require the trailing comma (return var,).@app.cell decorator or def _(...) signature → STOP. Marimo manages these; edit only the function body.marimo check → STOP. Execution with --include-outputs is required.Before every marimo edit:
Structure Validation:
@app.cell function bodiesSyntax Validation:
marimo check notebook.pyRuntime Verification:
marimo export ipynb notebook.py -o __marimo__/notebook.ipynb --include-outputsOnly after ALL checks pass:
Follow this sequence for EVERY marimo task:
1. EDIT → Modify code inside @app.cell function bodies only
2. CHECK → marimo check notebook.py
3. EXECUTE → marimo export ipynb notebook.py -o __marimo__/notebook.ipynb --include-outputs
4. INSPECT → Use notebook-debug verification
5. VERIFY → Outputs match expectations
6. CLAIM → "Notebook works" only after all gates passed
NEVER skip verification gates. Marimo's reactivity means changes propagate unpredictably.
.py files, version control friendly@app.cell decorator patternimport marimo
app = marimo.App()
@app.cell
def _(pl): # Dependencies as parameters
df = pl.read_csv("data.csv")
return df, # Trailing comma required for single return
@app.cell
def _(df, pl):
summary = df.describe()
filtered = df.filter(pl.col("value") > 0)
return summary, filtered # Multiple returns
@app.cell functions only$ in backticks - mo.md("Cost: $50") not mo.md("Cost: $50")| Command | Purpose |
|---------|---------|
| marimo edit notebook.py | marimo: Open notebook in browser editor for interactive development |
| marimo run notebook.py | marimo: Run notebook as executable app |
| marimo check notebook.py | marimo: Validate notebook structure and syntax without execution |
| marimo convert notebook.ipynb | marimo: Convert Jupyter notebook to marimo format |
# marimo: Export to ipynb with code only
marimo export ipynb notebook.py -o __marimo__/notebook.ipynb
# marimo: Export to ipynb with outputs (runs notebook first)
marimo export ipynb notebook.py -o __marimo__/notebook.ipynb --include-outputs
# marimo: Export to HTML (runs notebook by default)
marimo export html notebook.py -o __marimo__/notebook.html
# marimo: Export to HTML with auto-refresh on changes (live preview)
marimo export html notebook.py -o __marimo__/notebook.html --watch
Key difference: HTML export runs the notebook by default. ipynb export does NOT - use --include-outputs to run and capture outputs.
Tip: Use __marimo__/ folder for all exports (ipynb, html). The editor can auto-save there.
For working inside a running marimo notebook kernel — executing code, creating/editing cells, and building notebooks interactively — use the marimo-pair protocol. Full details: marimo-pair/SKILL.md.
See marimo-pair/reference/finding-marimo.md for the full decision tree. Quick start:
# pixi project (our standard)
pixi run marimo edit notebook.py --no-token --watch
# uv project
uv run marimo edit notebook.py --no-token --watch
# standalone / sandbox
uvx marimo@latest edit notebook.py --no-token --watch --sandbox
Always use --watch so the server detects file edits and reloads automatically. Without it, file changes are invisible to the browser and the user sees stale content.
Always start as a background task (run_in_background) so the server doesn't block the conversation. Do NOT use --headless unless asked — let marimo open the browser.
# Discover running servers
bash ${CLAUDE_SKILL_DIR}/marimo-pair/scripts/discover-servers.sh
# Execute code in the kernel (one-liner)
bash ${CLAUDE_SKILL_DIR}/marimo-pair/scripts/execute-code.sh -c "df.head()"
# Execute code (multiline — use heredoc to avoid shell escaping)
bash ${CLAUDE_SKILL_DIR}/marimo-pair/scripts/execute-code.sh <<'EOF'
import marimo._code_mode as cm
async with cm.get_context() as ctx:
cid = ctx.create_cell("x = 1")
ctx.run_cell(cid)
EOF
Use --port to target a specific server, --session for a specific notebook, --url for remote servers.
marimo._code_mode with async with cm.get_context() as ctx: to create/edit/delete cells and install packages. All ctx.* methods are synchronous — do NOT await them.create_cell and edit_cell are structural only — call ctx.run_cell(cid) to execute.ctx.install_packages(), not uv add or pip..py file directly while a session is running — the kernel owns it.marimo-pair/reference/finding-marimo.md — How to find and invoke the right marimo binarymarimo-pair/reference/gotchas.md — Cached module proxies and other trapsmarimo-pair/reference/rich-representations.md — Custom anywidgets, _display_(), Arrow IPC for large datamarimo-pair/reference/notebook-improvements.md — Setup cells, lifting functions, mo.persistent_cachemo.ui for interactive widgetsmo.sql(df, "SELECT * FROM df")mo.md("# Heading")1. Pre-execution validation:
# scripts: Validate notebook syntax and cell structure
scripts/check_notebook.sh notebook.py
Runs syntax check, marimo validation, and cell structure overview in one command.
2. Runtime errors: Export with outputs, then use notebook-debug skill:
# marimo: Export to ipynb with outputs for inspection
marimo export ipynb notebook.py -o __marimo__/notebook.ipynb --include-outputs
| Issue | Fix |
|-------|-----|
| Variable redefinition | Rename one variable or merge cells |
| Circular dependency | Break cycle by merging or restructuring |
| Missing return | Add return var, with trailing comma |
| Import not available | Ensure import cell returns the module |
For detailed patterns and advanced techniques, consult:
references/reactivity.md - DAG execution, variable rules, dependency detection patternsreferences/debugging.md - Error patterns, runtime debugging, environment-specific issuesreferences/widgets.md - Interactive UI components and mo.ui patternsreferences/sql.md - SQL cells and database integration techniquesmarimo-pair/reference/finding-marimo.md - How to find and invoke marimo across project typesmarimo-pair/reference/gotchas.md - Cached module proxies (e.g., polars + pyarrow mid-session)marimo-pair/reference/rich-representations.md - Custom anywidgets, Arrow IPC, _display_() protocolmarimo-pair/reference/notebook-improvements.md - Setup cells, lifting functions, mo.persistent_cacheWorking examples available in examples/:
examples/basic_notebook.py - Minimal marimo notebook structureexamples/data_analysis.py - Data loading, filtering, and visualization patternsexamples/interactive_widgets.py - Interactive UI component usageValidation and live-session utilities:
scripts/check_notebook.sh - Primary validation: syntax check, marimo validation, cell structure overviewscripts/get_cell_map.py - Extract cell metadata (invoked by check_notebook.sh)marimo-pair/scripts/discover-servers.sh - Find running marimo serversmarimo-pair/scripts/execute-code.sh - Execute code in a running marimo kernelnotebook-debug - Debugging executed ipynb files with tracebacks and output inspectionmarimo-pair/SKILL.md - Full marimo-pair protocol for live kernel interactiontools
Use when "query Dewey Data", "deweydata.io", "SafeGraph places/patterns/spend", "Advan foot traffic", "POI / points of interest", "mobility data", "dataplor", "Veraset", "PassBy", "crypto/Bitcoin ATM locations", or any pull from the Dewey Data academic marketplace (UVA/NYU Platform Subscription) via the deweypy/deweydatapy client, DuckDB, or the Dewey MCP server.
development
Use when submitting jobs to UVA HPC (Rivanna/Afton), writing Slurm scripts (sbatch/srun/squeue), converting SGE to Slurm, running compute on any Slurm-managed cluster, or building WRDS data pipelines with polars on HPC. Triggers: 'submit to HPC', 'sbatch', 'squeue', 'slurm job', 'run on Rivanna', 'run on Afton', 'HPC array job', 'convert SGE to Slurm', 'polars on HPC', 'WRDS from HPC'.
testing
Internal skill for literature review and source materialization. Called after brainstorm, before setup. NOT user-facing.
development
This skill should be used when the user asks to "add paper", "paperpile add", "fetch PDF for", "find and add", "search paperpile", "find in paperpile", "paperpile search", "label paper", "trash paper", "download paper", "paperpile index", "edit paper metadata", "update paper title", "fix paper author", "paperpile edit", "find PDF online", "search google for PDF", "resolve PDF", "fetch PDF for citation", "get full-text for DOI", "resolve cite to PDF", or any request to manage their Paperpile library or resolve a citation to a local PDF.