🍃 Share notebooks from GitHub!

Badge generator

marimo as a Streamlit alternative

marimo is a reactive Python notebook that doubles as a web app — no rewriting needed. Compare marimo vs Streamlit on performance, deployment, state management, and more.

marimo as a Streamlit alternative

Streamlit is great for building web apps quickly, but you lose the notebook experience that makes data exploration so powerful. marimo gives you both - an app-building experience that’s similar to Streamlit with the full power of notebooks. No rewriting, no context switching, no trade-offs.

Reactive execution vs. full reruns

The biggest performance difference between marimo and Streamlit comes down to how they execute code.

Streamlit reruns your entire script from top to bottom on every interaction — every slider change, every button click. As your app grows, this creates noticeable lag and forces you to add @st.cache_data decorators everywhere to keep things fast.

marimo uses a reactive execution model. When a cell changes, marimo only reruns the cells that depend on it. This means interacting with a slider only updates the cells downstream of that slider — not your entire notebook. The result is snappier apps with less boilerplate.

A notebook that becomes an app

Streamlit apps are written as Python scripts. You declare components that render on screen, but there’s no way to interactively explore data while building. marimo keeps the notebook experience front and center. You can run cells in any order, inspect variables, and experiment with code — the same workflow you’d use in Jupyter. Then, when you’re ready, the same notebook becomes a web app without rewriting anything.

This means faster development. You explore your data, build your analysis, and create your app interface all in one place. No copying code between a notebook and a separate Streamlit script. marimo also has built-in support for inline pytest tests, so you can verify your analysis works end-to-end directly in the same notebook file.

UI elements and layouts

In Streamlit, creating a UI element automatically renders it in the sidebar or main column. This is simple but limiting — you can’t easily reuse a widget in multiple places or build complex layouts.

In marimo, UI element creation is separated from display. You create a slider, then place it wherever you want — in a column, a tab, an accordion, or even multiple locations. This makes it straightforward to build custom dashboards and higher-order components. marimo also supports the anywidget spec, so you can embed custom interactive components like 3D visualizations directly in your notebook.

Reactive state management

In most cases, marimo’s reactive execution model means you don’t need explicit state management at all - variables defined in one cell are automatically available downstream and update when their dependencies change.

When you do need mutable state (like a counter or pagination), marimo provides mo.state(), which returns a getter/setter pair similar to React hooks. Updating state via the setter automatically reruns only the cells that depend on it. Streamlit’s st.session_state serves a similar purpose, but because Streamlit reruns the entire script on each interaction, managing state correctly requires more care to avoid bugs.

Native SQL support

marimo has built-in SQL support. You can query dataframes and databases directly from SQL cells, and the results flow into Python cells as regular dataframes. No need to set up API endpoints or write database wrapper code.

Both marimo and Streamlit require connection setup for databases. The difference is what happens after: marimo’s SQL cells automatically cast query results into dataframes that flow directly into Python cells downstream, making the transition between SQL and Python seamless.

Deployment options

Streamlit has one deployment model: run it as a web app server. marimo gives you several options from the same file:

  • Web app: Deploy with marimo run notebook.py
  • Command line: Run as a script with python notebook.py
  • Testing: Add inline pytest tests and run pytest notebook.py in CI
  • Browser-only: Export to WASM so users run everything in their browser — no server needed
  • Module: Import functions from a marimo notebook into other Python files

The same notebook works in all these modes without changes. Write once, deploy anywhere.

Built for AI agents

marimo notebooks are stored as pure Python, just like Streamlit scripts. But marimo’s reactive execution model gives AI agents something Streamlit can’t: deterministic state. An agent can edit a cell and know exactly which downstream cells will re-execute, making it a natural fit for agentic coding tools like Claude Code. Agents can also run marimo notebooks as scripts and inspect outputs programmatically — useful for testing and validation loops.

When to choose marimo over Streamlit

Choose marimo when you want:

  • Interactive exploration during development, not just in the final app
  • Reactive execution that only reruns what changed
  • Native SQL and database support without boilerplate
  • Multiple deployment targets (web, CLI, WASM, module)
  • Deterministic state that works well with AI coding agents
  • A single file that works for prototyping, production, and testing

Streamlit works well for simple, linear apps with basic data needs. marimo works better for complex analysis, real data workflows, and when you want the full power of notebooks plus web app deployment.

How to get started

marimo is free and open source. Install it with pip install marimo or uv add marimo and run marimo tutorial intro to get started. If you’re coming from Streamlit, the migration guide walks through the key differences step by step.