Marimo
by btimothy-har
This skill should be used when creating or editing marimo reactive notebooks. Keywords: marimo, reactive notebook, data app, mo.ui.
Skill Details
Repository Files
1 file in this skill directory
name: marimo description: This skill should be used when creating or editing marimo reactive notebooks. Keywords: marimo, reactive notebook, data app, mo.ui.
Marimo Reactive Notebooks
Extends the python-development skill. Marimo is a reactive Python notebook—stored as pure .py files, git-friendly, executable as scripts, and deployable as apps.
Principles
Reactivity
- Cells auto-run on change - Edit a cell, and marimo runs all dependent cells automatically
- No hidden state - Delete a cell, and its variables are scrubbed from memory
- Static analysis determines dependencies - Based on variable references, not cell order
- Deterministic execution - Notebooks always execute in the same order based on the DAG
Cell Rules
- One definition per variable - Variables cannot be redefined across cells
- Last expression is output - The final expression in a cell is automatically displayed
- Use
_prefix for private variables - Variables starting with_are cell-local - Assign UI elements to globals - UI elements must be assigned to global variables to be reactive
Data Flow
- UI elements are reactive - Interact with a slider, and dependent cells re-run
- Access values via
.value- All UI elements have a.valueattribute - No callbacks needed - Reactivity handles updates automatically
Installation
Add to pyproject.toml:
[project]
dependencies = [
"marimo",
]
# For SQL support
[project.optional-dependencies]
sql = ["marimo[sql]"]
CLI Commands
uv run marimo edit notebook.py # Open/create notebook in editor
uv run marimo run notebook.py # Run as app (code hidden)
uv run marimo edit --headless # Run without opening browser
uv run marimo tutorial intro # Run interactive tutorial
uv run marimo convert notebook.ipynb > notebook.py # Convert from Jupyter
Notebook Structure
Marimo notebooks are pure Python files:
import marimo
app = marimo.App()
@app.cell
def _():
import marimo as mo
import pandas as pd
return mo, pd
@app.cell
def _(mo):
slider = mo.ui.slider(1, 100, value=50, label="Count")
slider
return slider,
@app.cell
def _(slider, pd):
# This cell re-runs when slider changes
df = pd.DataFrame({"values": range(slider.value)})
df
return df,
if __name__ == "__main__":
app.run()
UI Elements
Basic Inputs
import marimo as mo
# Slider
slider = mo.ui.slider(start=0, stop=100, value=50, step=1, label="Value")
# Number input
number = mo.ui.number(start=0, stop=100, value=10, label="Count")
# Text input
text = mo.ui.text(value="", label="Name", placeholder="Enter name")
# Text area
textarea = mo.ui.text_area(value="", label="Description")
# Checkbox
checkbox = mo.ui.checkbox(label="Enable feature", value=False)
# Dropdown
dropdown = mo.ui.dropdown(
options=["Option A", "Option B", "Option C"],
value="Option A",
label="Choose one",
)
# Dropdown with key-value pairs
dropdown_kv = mo.ui.dropdown(
options={"Label 1": "value1", "Label 2": "value2"},
value="Label 1",
label="Select",
)
# Radio buttons
radio = mo.ui.radio(
options=["Small", "Medium", "Large"],
value="Medium",
label="Size",
)
# Multiselect
multiselect = mo.ui.multiselect(
options=["A", "B", "C", "D"],
label="Select multiple",
)
# Date picker
date = mo.ui.date(label="Select date")
# File upload
file = mo.ui.file(filetypes=[".csv", ".json"], label="Upload file")
# Button
button = mo.ui.button(label="Click me", kind="primary")
# Run button (triggers cell re-run)
run_button = mo.ui.run_button(label="Run analysis")
Accessing Values
@app.cell
def _(slider, dropdown, checkbox):
# Access current values
count = slider.value # int
choice = dropdown.value # str
enabled = checkbox.value # bool
mo.md(f"Count: {count}, Choice: {choice}, Enabled: {enabled}")
Data Components
# Interactive dataframe viewer
mo.ui.dataframe(df)
# Data explorer with visualizations
mo.ui.data_explorer(df)
# Interactive table with selection
table = mo.ui.table(
data=df,
selection="multi", # or "single"
pagination=True,
)
# Access selected rows: table.value
Markdown
import marimo as mo
# Basic markdown
mo.md("# Hello World")
# Markdown with Python values
name = "marimo"
mo.md(f"Welcome to **{name}**!")
# Embed UI elements in markdown
slider = mo.ui.slider(1, 10, label="Value")
mo.md(f"Choose a value: {slider}")
# LaTeX support
mo.md(r"The formula is $E = mc^2$")
# Multi-line with f-string
mo.md(f"""
# Analysis Results
- **Count**: {slider.value}
- **Status**: {"Active" if slider.value > 5 else "Inactive"}
""")
Layout
import marimo as mo
# Horizontal stack
mo.hstack([element1, element2, element3], justify="center", gap=2)
# Vertical stack
mo.vstack([element1, element2], align="start", gap=1)
# Tabs
mo.ui.tabs({
"Tab 1": content1,
"Tab 2": content2,
"Tab 3": content3,
})
# Accordion
mo.accordion({
"Section 1": content1,
"Section 2": content2,
})
# Callout boxes
mo.callout("Important message", kind="info") # info, warn, danger, success
# Grid layout
mo.ui.batch(
mo.md("""
| Setting | Value |
|---------|-------|
| Name | {name} |
| Count | {count} |
"""),
name=mo.ui.text(),
count=mo.ui.number(start=0, stop=100),
)
Forms
Group UI elements and submit together:
# Create a form that submits on button click
form = mo.md("""
**Configuration**
- Epsilon: {epsilon}
- Delta: {delta}
- Name: {name}
""").batch(
epsilon=mo.ui.slider(0.1, 1.0, step=0.1, value=0.5),
delta=mo.ui.number(start=1, stop=10, value=5),
name=mo.ui.text(value="default"),
).form(submit_button_label="Apply")
# Display the form
form
# Access submitted values (None until submitted)
if form.value:
epsilon = form.value["epsilon"]
delta = form.value["delta"]
SQL Integration
import marimo as mo
# SQL cells return dataframes
df = mo.sql(f"""
SELECT *
FROM my_table
WHERE count > {slider.value}
LIMIT 100
""")
# Use with DuckDB (auto-detected)
import duckdb
conn = duckdb.connect("data.db")
# Query Python dataframes directly
df = mo.sql(f"""
SELECT * FROM df_source
WHERE category = '{dropdown.value}'
""")
Plotting
import marimo as mo
import altair as alt
# Altair charts are automatically interactive
chart = alt.Chart(df).mark_point().encode(
x="x:Q",
y="y:Q",
color="category:N",
)
chart
# Make chart selectable
selectable_chart = mo.ui.altair_chart(chart)
# Access selected points: selectable_chart.value
Caching
import marimo as mo
@mo.cache
def expensive_computation(x: int) -> int:
# Result is cached based on input
return x ** 2
# Or cache to disk
@mo.cache(pin=True)
def load_large_dataset(path: str):
return pd.read_parquet(path)
Running as Script/App
# Run as script (cells execute in topological order)
uv run python notebook.py
# Run as interactive app (code hidden)
uv run marimo run notebook.py
# Run with CLI args
uv run marimo run notebook.py -- --param1 value1
Lazy Execution Mode
For expensive notebooks, mark cells as stale instead of auto-running:
# In notebook settings or via CLI
uv run marimo edit notebook.py --lazy
Common Patterns
Conditional Display
@app.cell
def _(checkbox, data):
if checkbox.value:
result = mo.md(f"Data: {data}")
else:
result = mo.md("Enable checkbox to see data")
result
Dynamic UI Elements
@app.cell
def _(count_slider):
# Create dynamic number of inputs
inputs = mo.ui.array([
mo.ui.text(label=f"Item {i}")
for i in range(count_slider.value)
])
inputs
@app.cell
def _(inputs):
# Access all values
values = inputs.value # List of strings
mo.md(f"Values: {values}")
Stop Execution
@app.cell
def _(data):
# Stop cell execution if condition not met
mo.stop(data is None, mo.md("**Waiting for data...**"))
# Continue processing
result = process(data)
result
Important Notes
- No variable redefinition - Each variable can only be defined in one cell
- Use
_prefix for cell-local variables -_temp = compute()won't leak - Notebooks are DAGs - Execution order is determined by dependencies, not position
- Pure Python files - Version control, import, test with standard tools
- UI elements must be global - Assign to variables without
_prefix for reactivity
Related Skills
Xlsx
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Analyzing Financial Statements
This skill calculates key financial ratios and metrics from financial statement data for investment analysis
Data Storytelling
Transform data into compelling narratives using visualization, context, and persuasive structure. Use when presenting analytics to stakeholders, creating data reports, or building executive presentations.
Kpi Dashboard Design
Design effective KPI dashboards with metrics selection, visualization best practices, and real-time monitoring patterns. Use when building business dashboards, selecting metrics, or designing data visualization layouts.
Dbt Transformation Patterns
Master dbt (data build tool) for analytics engineering with model organization, testing, documentation, and incremental strategies. Use when building data transformations, creating data models, or implementing analytics engineering best practices.
Sql Optimization Patterns
Master SQL query optimization, indexing strategies, and EXPLAIN analysis to dramatically improve database performance and eliminate slow queries. Use when debugging slow queries, designing database schemas, or optimizing application performance.
Anndata
This skill should be used when working with annotated data matrices in Python, particularly for single-cell genomics analysis, managing experimental measurements with metadata, or handling large-scale biological datasets. Use when tasks involve AnnData objects, h5ad files, single-cell RNA-seq data, or integration with scanpy/scverse tools.
Xlsx
Spreadsheet toolkit (.xlsx/.csv). Create/edit with formulas/formatting, analyze data, visualization, recalculate formulas, for spreadsheet processing and analysis.
