marimo-editor
This skill should be used when working with marimo reactive notebooks for data science and analytics.Triggers include:- Creating new marimo notebooks- Converting Jupyter notebooks to marimo- Editing existing marimo notebooks- Implementing reactive patterns and UI components- Building interactive data visualizations with marimo
When & Why to Use This Skill
This Claude skill provides expert guidance for developing reactive data science notebooks using marimo. It enables users to create reproducible, interactive, and high-performance data analysis workflows by leveraging marimo's unique directed acyclic graph (DAG) execution model, ensuring that code remains clean and visualizations stay synchronized with data changes.
Use Cases
- Converting legacy Jupyter notebooks to marimo to eliminate hidden state issues and improve reproducibility.
- Building interactive data dashboards with reactive UI components like sliders, dropdowns, and data explorers for real-time parameter tuning.
- Performing SQL-based data analysis using integrated DuckDB cells to query dataframes and visualize results seamlessly.
- Developing complex data visualizations using Altair, Plotly, or Matplotlib that automatically update based on user input or data changes.
- Implementing clean, modular data science projects that follow best practices for variable declaration and dependency management.
| name | marimo-editor |
|---|---|
| description | | |
Marimo Notebook Assistant
This skill provides specialized guidance for creating data science notebooks using marimo's reactive programming model. Focus on creating clear, efficient, and reproducible data analysis workflows.
Core Capabilities
- Data science and analytics using marimo notebooks
- Complete, runnable code that follows best practices
- Reproducibility and clear documentation
- Interactive data visualizations and analysis
- Understanding of marimo's reactive programming model
Marimo Fundamentals
Marimo is a reactive notebook that differs from traditional notebooks in key ways:
- Cells execute automatically when their dependencies change
- Variables cannot be redeclared across cells
- The notebook forms a directed acyclic graph (DAG)
- The last expression in a cell is automatically displayed
- UI elements are reactive and update the notebook automatically
Code Requirements
- All code must be complete and runnable
- Follow consistent coding style throughout
- Include descriptive variable names and helpful comments
- Import all modules in the first cell, always including
import marimo as mo - Never redeclare variables across cells
- Ensure no cycles in notebook dependency graph
- The last expression in a cell is automatically displayed, just like in Jupyter notebooks
- Don't include comments in markdown cells
- Don't include comments in SQL cells
Reactivity
Marimo's reactivity means:
- When a variable changes, all cells that use that variable automatically re-execute
- UI elements trigger updates when their values change without explicit callbacks
- UI element values are accessed through
.valueattribute - Cannot access a UI element's value in the same cell where it's defined
Best Practices
Data Handling
- Use pandas for data manipulation
- Implement proper data validation
- Handle missing values appropriately
- Use efficient data structures
- A variable in the last expression of a cell is automatically displayed as a table
Visualization
- For matplotlib: use
plt.gca()as the last expression instead ofplt.show() - For plotly: return the figure object directly
- For altair: return the chart object directly
- Include proper labels, titles, and color schemes
- Make visualizations interactive where appropriate
UI Elements
- Access UI element values with
.valueattribute (e.g.,slider.value) - Create UI elements in one cell and reference them in later cells
- Create intuitive layouts with
mo.hstack(),mo.vstack(), andmo.tabs() - Prefer reactive updates over callbacks (marimo handles reactivity automatically)
- Group related UI elements for better organization
Data Sources
- Prefer GitHub-hosted datasets (e.g., raw.githubusercontent.com)
- Use CORS proxy for external URLs: https://corsproxy.marimo.app/
- Implement proper error handling for data loading
- Consider using
vega_datasetsfor common example datasets
SQL
- When writing duckdb, prefer using marimo's SQL cells, which start with
_df = mo.sql(query) - See the SQL with duckdb example for an example on how to do this
- Don't add comments in cells that use
mo.sql() - Consider using
vega_datasetsfor common example datasets
Troubleshooting
Common issues and solutions:
- Circular dependencies: Reorganize code to remove cycles in the dependency graph
- UI element value access: Move access to a separate cell from definition
- Visualization not showing: Ensure the visualization object is the last expression
Available UI Elements
mo.ui.altair_chart(altair_chart)mo.ui.button(value=None, kind='primary')mo.ui.run_button(label=None, tooltip=None, kind='primary')mo.ui.checkbox(label='', value=False)mo.ui.date(value=None, label=None, full_width=False)mo.ui.dropdown(options, value=None, label=None, full_width=False)mo.ui.file(label='', multiple=False, full_width=False)mo.ui.number(value=None, label=None, full_width=False)mo.ui.radio(options, value=None, label=None, full_width=False)mo.ui.refresh(options: List[str], default_interval: str)mo.ui.slider(start, stop, value=None, label=None, full_width=False, step=None)mo.ui.range_slider(start, stop, value=None, label=None, full_width=False, step=None)mo.ui.table(data, columns=None, on_select=None, sortable=True, filterable=True)mo.ui.text(value='', label=None, full_width=False)mo.ui.text_area(value='', label=None, full_width=False)mo.ui.data_explorer(df)mo.ui.dataframe(df)mo.ui.plotly(plotly_figure)mo.ui.tabs(elements: dict[str, mo.ui.Element])mo.ui.array(elements: list[mo.ui.Element])mo.ui.form(element: mo.ui.Element, label='', bordered=True)
Layout and Utility Functions
mo.md(text)- display markdownmo.stop(predicate, output=None)- stop execution conditionallymo.Html(html)- display HTMLmo.image(image)- display an imagemo.hstack(elements)- stack elements horizontallymo.vstack(elements)- stack elements verticallymo.tabs(elements)- create a tabbed interface
Examples
Basic UI with Reactivity
# Cell 1
import marimo as mo
import matplotlib.pyplot as plt
import numpy as np
# Cell 2
# Create a slider and display it
n_points = mo.ui.slider(10, 100, value=50, label="Number of points")
n_points # Display the slider
# Cell 3
# Generate random data based on slider value
# This cell automatically re-executes when n_points.value changes
x = np.random.rand(n_points.value)
y = np.random.rand(n_points.value)
plt.figure(figsize=(8, 6))
plt.scatter(x, y, alpha=0.7)
plt.title(f"Scatter plot with {n_points.value} points")
plt.xlabel("X axis")
plt.ylabel("Y axis")
plt.gca() # Return the current axes to display the plot
Data Explorer
# Cell 1
import marimo as mo
import pandas as pd
from vega_datasets import data
# Cell 2
# Load and display dataset with interactive explorer
cars_df = data.cars()
mo.ui.data_explorer(cars_df)
Multiple UI Elements
# Cell 1
import marimo as mo
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# Cell 2
# Load dataset
iris = sns.load_dataset('iris')
# Cell 3
# Create UI elements
species_selector = mo.ui.dropdown(
options=["All"] + iris["species"].unique().tolist(),
value="All",
label="Species"
)
x_feature = mo.ui.dropdown(
options=iris.select_dtypes('number').columns.tolist(),
value="sepal_length",
label="X Feature"
)
y_feature = mo.ui.dropdown(
options=iris.select_dtypes('number').columns.tolist(),
value="sepal_width",
label="Y Feature"
)
# Display UI elements in a horizontal stack
mo.hstack([species_selector, x_feature, y_feature])
# Cell 4
# Filter data based on selection
filtered_data = iris if species_selector.value == "All" else iris[iris["species"] == species_selector.value]
# Create visualization based on UI selections
plt.figure(figsize=(10, 6))
sns.scatterplot(
data=filtered_data,
x=x_feature.value,
y=y_feature.value,
hue="species"
)
plt.title(f"{y_feature.value} vs {x_feature.value}")
plt.gca()
Interactive Chart with Altair
# Cell 1
import marimo as mo
import altair as alt
import pandas as pd
# Cell 2
# Load dataset
cars_df = pd.read_csv('https://raw.githubusercontent.com/vega/vega-datasets/master/data/cars.json')
_chart = alt.Chart(cars_df).mark_point().encode(
x='Horsepower',
y='Miles_per_Gallon',
color='Origin',
)
chart = mo.ui.altair_chart(_chart)
chart
# Cell 3
# Display the selection
chart.value
Run Button Example
# Cell 1
import marimo as mo
# Cell 2
first_button = mo.ui.run_button(label="Option 1")
second_button = mo.ui.run_button(label="Option 2")
[first_button, second_button]
# Cell 3
if first_button.value:
print("You chose option 1!")
elif second_button.value:
print("You chose option 2!")
else:
print("Click a button!")
SQL with DuckDB
# Cell 1
import marimo as mo
# Cell 2
# Load dataset
cars_df = pd.read_csv('https://raw.githubusercontent.com/vega/vega-datasets/master/data/cars.json')
# Cell 3
_df = mo.sql("SELECT * from cars_df WHERE Miles_per_Gallon > 20")
Writing LaTeX in Markdown
# Cell 1
import marimo as mo
# Cell 2
mo.md(r"""
The quadratic function $f$ is defined as
$$f(x) = x^2.$$
""")