marimo: Reactive Python Notebook
marimo is an open-source Python notebook in which cells re-execute automatically when the variables they read change. Notebooks are stored as plain .py files rather than JSON and are parsed by static analysis to derive a deterministic execution order. The same file can be run as a standalone script or inside a sandboxed environment managed by uv. It is licensed under Apache-2.0 and requires Python 3.10 or newer.
Reactive Notebook Model
The traditional notebook model decouples cell ordering from execution. A Jupyter cell runs only when the user runs it, so the in-memory kernel state can drift from the visible code. Variables outlive the cells that defined them, and re-running cells out of order produces results that a fresh kernel restart cannot reproduce. This is the hidden state problem.
marimo replaces that model with rules enforced by the runtime:
- Reactive execution: editing or running a cell triggers every cell that reads its outputs, in topological order. The runtime can mark dependent cells stale instead of running them, configurable per notebook.
- Variables are bound in exactly one cell: defining the same name in two cells is a hard error rather than a race. Deleting a cell removes its bindings from memory immediately.
- Pure-Python file format: each cell is a function in a
.pyfile, and the notebook itself is a valid Python module.git diffshows code, not JSON, andpython notebook.pyruns the cells in dependency order with no marimo runtime required.
Because the file is plain Python, marimo notebooks accept PEP 723 inline script metadata. Sandboxed mode reads that header, hands it to uv, and runs the notebook in an isolated virtual environment that contains only the declared dependencies.
Key Features
- Reactive runtime: cells re-run on variable change with no manual “restart and run all” step.
- Built-in UI elements: sliders, dropdowns, tables, file pickers, and selectable plots bind to Python variables without callback wiring, and updating a widget triggers the same reactive update path as editing a cell.
- SQL cells: cells written in SQL execute against DuckDB by default and can be pointed at SQLite, PostgreSQL, or MySQL. Results return as Polars or pandas dataframes for downstream Python cells.
- Multiple run modes:
marimo editopens the interactive editor,marimo runserves a notebook as a read-only web app with code hidden,python notebook.pyexecutes the cells as a script, andmarimo exportproduces HTML, ipynb, or a self-contained WASM bundle. - Sandboxed dependencies: with the
sandboxextra installed and uv onPATH,--sandboxnotebooks track their own pinned dependencies in a PEP 723 header and reproduce a fresh environment on every launch. - Jupyter conversion:
marimo convert notebook.ipynbrewrites an existing Jupyter notebook into a marimo.pyfile, removing the JSON wrapper and inferring cell-level dependencies where possible. - AI integration: the editor includes a Copilot-style completion panel, and
marimo pairexposes the notebook context to coding agents like Claude Code and Codex.marimo new "prompt"generates a notebook from a natural-language description.
Installation and Usage
The recommended install path uses uv so marimo and its dependencies stay isolated from the system Python.
# Install once as a global tool
uv tool install "marimo[recommended]"
# Or run without installing
uvx marimo edit notebook.py
# Or add to a project
uv add marimoThe bare marimo distribution is minimal. The recommended extra pulls in DuckDB, Polars, Altair, sqlglot, Ruff, and nbformat so SQL cells, dataframe rendering, server-side plotting, and Jupyter import work without further installs. The sandbox extra adds pyzmq and uv for PEP 723 sandboxing.
Common entry points:
marimo new # empty notebook in a fresh editor session
marimo edit notebook.py # create or open notebook.py
marimo edit --sandbox notebook.py # run inside a uv-managed isolated env
marimo run notebook.py # serve as a read-only web app
marimo convert legacy.ipynb # rewrite a Jupyter notebook as marimo
marimo export html notebook.py # produce a static HTML export
python notebook.py # execute the notebook as a regular scriptPros
- Reactive runtime re-runs dependent cells automatically, so reproducing results does not require a fresh kernel restart.
- Pure-Python file format produces reviewable diffs and works with every linter, formatter, and type checker that runs on regular Python source.
- PEP 723 sandboxing pins the Python version and dependencies inside the notebook file itself.
- Editor, read-only web app, and script runner ship in one package.
Cons
- Variable-uniqueness rule and reactive runtime require restructuring notebooks ported from Jupyter; not every Jupyter idiom translates cleanly.
- Smaller plugin and kernel ecosystem than Jupyter, with no support for non-Python kernels.
- Static analysis of cell dependencies has corner cases (closures and decorators that rebind names) that surface as errors in code that mutates module-level state.
- Younger project than the Jupyter stack (first PyPI release August 2023), with a smaller public corpus of examples and Stack Overflow answers.
Learn More
- marimo documentation covers the editor, reactive model, and deployment workflow.
- marimo on GitHub holds the source, release notes, and issue tracker.
- Migrate from Jupyter to marimo explains the conversion path and the patterns that change.
- marimo: A Reactive, Reproducible Notebook is Real Python’s long-form walkthrough.
- How to run a Jupyter notebook with uv shows the equivalent uv workflow with classic Jupyter.
- What is PEP 723 describes the inline script metadata format that marimo uses for sandboxing.