MA

marimo

Reactive Python notebook that runs as a web app

Developer Tools & Git ★ 22.9k stars Easy setup Apache-2.0

marimo is an open-source reactive notebook for Python where cells automatically re-run when their dependencies change. Notebooks are stored as pure Python files and can be deployed as interactive web apps.

Key features

  • Reactive cell execution
  • Notebooks stored as Python
  • Deploy as web apps
  • Reproducible by design

Pros & cons

Strengths

  • Reactive cell execution
  • Notebooks are pure Python
  • Deployable as web apps

Trade-offs

  • Not ipynb compatible
  • Smaller ecosystem than Jupyter

marimo replaces

Last reviewed Aug 26, 2026 · 714 words

A marimo notebook is a .py file. That single design decision fixes the three things that make Jupyter miserable to self-host: notebooks diff cleanly in git, they run top to bottom as a script with python notebook.py, and they serve as a web app with marimo run notebook.py and no rewrite. Add reactive execution, where changing a cell re-runs every cell that depends on it and nothing else, and hidden-state bugs disappear. The cost is that .ipynb files do not open here, and the extension ecosystem is a fraction of Jupyter's. For a personal or small-team analysis box I now default to marimo and keep JupyterLab around for the occasional notebook someone sends me.

Reactive means no stale cells

marimo parses each cell to find which variables it defines and which it reads, builds a dependency graph, and refuses to let two cells define the same variable. Run a cell and its dependents re-run automatically; delete a cell and its variables vanish everywhere. The practical consequence is that the notebook you see is always the notebook a fresh run would produce. For expensive computations you can switch to lazy mode, where dependents are marked stale rather than re-run. Anyone who has debugged a Jupyter notebook that only worked because cell 14 ran before cell 9 will understand why this is the headline feature.

Install, edit, run

pip install marimo
marimo edit analysis.py                                  # editor on port 2718
marimo run analysis.py --host 0.0.0.0 --port 2718 --headless

edit is the notebook environment. run serves the same file as a read-only app: code hidden, UI elements (sliders, dropdowns, tables, file pickers) live, and each visitor gets their own kernel session. Because the file is Python, the conversion from "my exploration" to "the dashboard the team uses" is zero lines of code, which is what Streamlit users will recognise, except here the exploration and the app are the same file.

marimo convert notebook.ipynb -o notebook.py imports a Jupyter notebook. Expect to fix duplicate variable definitions afterwards, because Jupyter allowed them and marimo will not.

Serving it as a self-hosted app

marimo run on port 2718 behind your reverse proxy is the whole deployment for a small team. Two details matter. First, marimo generates an access token by default and prints the URL with it; pass --no-token only if the proxy does the login, which it should. Second, each user's session is a Python process holding your data in memory, so the 512 MB rating covers one idle notebook; budget from 500 MB to a few GB per concurrent user depending on the dataframes involved.

FROM python:3.12-slim
RUN pip install marimo pandas
COPY analysis.py /app/analysis.py
CMD ["marimo", "run", "/app/analysis.py", "--host", "0.0.0.0", "--port", "2718", "--headless", "--no-token"]

For dependencies, marimo can write them into the script header using inline metadata and run with --sandbox to build an isolated environment through uv, which makes a notebook self-contained: one file, all requirements declared inside it.

Multi-user is where it stops

marimo has no user accounts, no sharing model and no scheduler. For a team that needs per-user servers with login, JupyterHub remains the answer, and marimo runs inside it as a server extension, so the two are not rivals. If your users are 3 people behind Authentik on a proxy, marimo alone is enough. If they are 30, put JupyterHub in front. There is also a WASM export (marimo export html-wasm) that turns a notebook into a static page running Python in the browser, which for a public demo removes the server entirely.

What I'd do

Install marimo in the project's virtualenv, keep notebooks in the repo next to the code because they are code, and serve the 2 or 3 that turned into dashboards with marimo run behind the reverse proxy, with the proxy handling login. Convert old Jupyter notebooks only when I need to touch them. For anything public and read-only, export to WASM and host it as static files. The dev tools category has the rest of the workbench.

Compare marimo

2 head-to-head comparisons.

Similar developer tools & git apps