# 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](https://pydevtools.com/handbook/reference/uv.md). 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 `.py` file, and the notebook itself is a valid Python module. `git diff` shows code, not JSON, and `python notebook.py` runs the cells in dependency order with no marimo runtime required.

Because the file is plain Python, marimo notebooks accept [PEP 723](https://pydevtools.com/handbook/explanation/what-is-pep-723.md) 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 edit` opens the interactive editor, `marimo run` serves a notebook as a read-only web app with code hidden, `python notebook.py` executes the cells as a script, and `marimo export` produces HTML, ipynb, or a self-contained WASM bundle.
- Sandboxed dependencies: with the `sandbox` extra installed and uv on `PATH`, `--sandbox` notebooks track their own pinned dependencies in a PEP 723 header and reproduce a fresh environment on every launch.
- Jupyter conversion: `marimo convert notebook.ipynb` rewrites an existing Jupyter notebook into a marimo `.py` file, removing the JSON wrapper and inferring cell-level dependencies where possible.
- AI integration: the editor includes a Copilot-style completion panel, and `marimo pair` exposes 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](https://pydevtools.com/handbook/reference/uv.md) so marimo and its dependencies stay isolated from the system Python.

```bash
# 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 marimo
```

The bare `marimo` distribution is minimal. The `recommended` extra pulls in DuckDB, Polars, Altair, sqlglot, [Ruff](https://pydevtools.com/handbook/reference/ruff.md), 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:

```bash
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 script
```

## Pros

- 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](https://docs.marimo.io/) covers the editor, reactive model, and deployment workflow.
- [marimo on GitHub](https://github.com/marimo-team/marimo) holds the source, release notes, and issue tracker.
- [Migrate from Jupyter to marimo](https://docs.marimo.io/guides/coming_from/jupyter/) explains the conversion path and the patterns that change.
- [marimo: A Reactive, Reproducible Notebook](https://realpython.com/marimo-notebook/) is Real Python's long-form walkthrough.
- [How to run a Jupyter notebook with uv](https://pydevtools.com/handbook/how-to/jupyter-notebook-with-uv.md) shows the equivalent uv workflow with classic Jupyter.
- [What is PEP 723](https://pydevtools.com/handbook/explanation/what-is-pep-723.md) describes the inline script metadata format that marimo uses for sandboxing.
