marimo: The Reactive Python Notebook
slide 01 of 28
Welcome to marimo
This course is a complete, research-grounded tour ofmarimo— the reactive Python notebook that stores notebooks as pure.pyfiles and re-runs cells automatically when their inputs change.
What you will learn
- Module 1— the theory: why traditional notebooks break, and why marimo's reactive model matters.
- Module 2— installation and your first notebook.
- Module 3— the reactive execution model, under the hood.
- Module 4— building interactive apps with UI elements, SQL, and charts.
- Module 5— marimo as a platform: scripts, web apps, modules, Git, deployment.
- Module 6— AI agents, the ecosystem, and where marimo is heading.
How to use this course
Each module ends with a short knowledge check. The final assessment gates your certificate. You can navigate with the arrow keys or the prev/next buttons, and mark pages as done as you go.
Tip:marimo is a moving target — it hit 1.0 and is under active development. Where a version number or star count is cited, it reflects the state at the time of writing (2026). Always check the official docs for the latest.
slide 02 of 28
The Notebook Problem
For over a decade, Jupyter-style notebooks have been the default tool for exploratory data work. They are beloved for good reason: you can run a cell, see a chart, tweak a value, and iterate fast.
But the classic notebook has a structural flaw that every serious user has hit:hidden state.
The hidden-state bug
In a traditional notebook, you run cells manually, in whatever order you like. The kernel keeps state between executions. Nothing stops you from running cell 7 before cell 3. Variables linger in memory after you edit or delete the cell that created them.
The result: a notebook that runs top-to-bottom on a fresh kernel producesdifferent resultsthan the one you have been interactively editing for an hour. You share a.ipynbwith a colleague and they say "it doesn't run." You know the pain.
Why this is more than an annoyance
Hidden state is not just a UX quirk. It is areproducibilityproblem:
- A chart drawn from a variable you changed three cells below.
- A result that only works because of a cell you deleted but whose value still lives in memory.
- A notebook that cannot be trusted as a record of how a result was produced.
In research, in reporting, and in anything that feeds a decision, this is a real liability.
The second problem: the file format
A.ipynbfile is JSON — a giant blob of metadata, outputs, and base64-encoded images. Git diffs are painful. Code review is nearly impossible. The notebook is not a program you can lint, test, or version cleanly.
The core insight:marimo was built to fix both of these problems at once — the execution model and the file format.
slide 03 of 28
What marimo Is
marimois a reactive Python notebook. It is open source (Apache-2.0), created by Akshay Agrawal and Myles Scolnick, and backed by Marimo Inc.
The three defining bets
- Reactive execution.Each cell declares what it reads and what it writes. Change a cell, and every cell that depends on it re-runs automatically, in the correct order. The notebook is adirected acyclic graph (DAG), not a script you click through.
- Pure Python storage.A marimo notebook is a plain
.pyfile. Each cell is a function decorated with@app.cell. It is Git-friendly, diffable, lintable, and testable. - One file, three ways to run it.The same notebook runs as an interactive editor (
marimo edit), as a command-line script (python notebook.py), and as a read-only web app (marimo run notebook.py).
The spreadsheet analogy
The marimo team's favorite framing: a marimo notebook behaves like aspreadsheet. Change a value and everything that depends on it updates on its own. You never click "Run All" and pray. You never end up with a chart drawn from a variable you changed three cells below.
What it is not
- It isnota Jupyter replacement for every use case — it is Python-only (no R, Julia, or Scala kernels).
- It isnota full production deployment platform out of the box —
marimo runis local-first; you still host it yourself. - It isnota magic bullet — reactive thinking is a new pattern you have to learn.
Fun fact:the name "marimo" comes from the Japanese word for a species of green algae that forms a perfect sphere — a nod to the idea of a self-contained, reproducible unit.
slide 04 of 28
Why marimo Matters Now
marimo is not just a nicer notebook. It arrived at a moment when three forces converged.
1. The reproducibility crisis in data work
Teams are tired of "it works on my machine" notebooks. marimo's deterministic execution and pure-Python storage make reproducibility thedefault, not a discipline you have to enforce.
2. The rise of AI agents
This is the big one. Because a marimo notebook is a plain.pyfile, an AI coding agent can read, write, and edit it with standard file tools — no special notebook parser needed. And because execution is a DAG, the agent does not have to guess which cells to re-run; the runtime handles it.
marimo has leaned into this hard withmarimo pair, a skill that drops an agentinsidea running notebook session, and an AI-native editor with copilots, inline edits, and context-aware chat.
3. The notebook-as-app shift
marimo run notebook.pyturns a notebook into an interactive web app with no separate framework. The notebookisthe app. This collapses the gap between exploration and delivery.
The numbers (as of 2026)
- marimo hit1.0and is used in production by teams that value reproducibility.
- The GitHub repo has grown to roughly20,000+ stars.
- Marimo Inc. raised a$5M seed roundin November 2024, led by AIX Ventures, with participation from Jeff Dean, Clément Delangue, Charlie Marsh, and others.
Why this matters to you:if you do data work, research, or build internal tools, marimo is a credible, well-funded, actively-developed answer to the notebook's oldest problems — and it is built for the agentic era.
slide 05 of 28
Pros and Cons
Let's be honest about what marimo gives you and what it costs.
Pros
- Reproducible by design.Deterministic execution order; no hidden state. A fresh run always matches what you see.
- Git-native.Pure
.pyfiles mean clean diffs, real code review, and easy versioning. - Reactive UI.Built-in widgets (sliders, dropdowns, tables, forms) that re-run dependent cells automatically — no callbacks to wire.
- One file, three modes.Edit interactively, run as a script, or serve as a web app.
- SQL built in.
mo.sqlruns SQL against DuckDB, Polars, Pandas, and more, returning DataFrames. - AI-native.Works with coding agents, has an AI editor, and supports marimo pair.
- Testable and lintable.It is just Python — use pytest, ruff, and your normal tooling.
Cons
- Python only.No R, Julia, or Scala kernels. If you need those, Jupyter is still your option.
- Younger ecosystem.Jupyter has a 10+ year head start in extensions, integrations, and tutorials.
- New mental model.Reactive DAG thinking and "no global state" take getting used to.
- Local-first deployment.
marimo rundoes not give you auth, HTTPS, and uptime monitoring out of the box. - Conversion is not free.Migrating a
.ipynbthat relies on execution-order tricks or%%magics needs manual cleanup.
The honest verdict:pick marimo when reproducibility, clean diffs, and reactive dataflow are first-order requirements. Pick Jupyter when you need the ecosystem or multi-language kernels. For many teams, the answer is "both, for different jobs."
slide 06 of 28
Installing marimo
marimo is a Python package, so installation is straightforward. The recommended path usesuv, but plainpipworks too.
With uv (recommended)
<code class="language-bash">uv pip install marimoWith pip
<code class="language-bash">pip install marimoVerify the install
<code class="language-bash">marimo --versionYou should see a version number. As of 2026, marimo is past 1.0 and releases frequently (versions like 0.23.x and beyond).
The sandbox flag
marimo integrates tightly withuvthrough a--sandboxflag, which creates an isolated environment for a notebook so its dependencies are reproducible and self-contained. This is a key part of marimo's reproducibility story.
Tip:use a virtual environment oruvproject for each notebook so dependencies stay pinned and reproducible. marimo supports PEP 723 inline metadata for declaring dependencies right in the file.slide 07 of 28
Your First Notebook
Create and open a notebook with a single command.
<code class="language-bash">marimo edit notebook.pyThis opens the marimo editor in your browser and createsnotebook.pyif it does not exist.
What you see
- A list ofcells, each a small Python block.
- Arunbutton per cell.
- Adependency graphview that shows how cells connect.
- Apackage managerto add dependencies.
Your first cells
Cell 1 — a value:
<code class="language-python">import marimo as mo
x = 10Cell 2 — something that depends on it:
<code class="language-python">y = x * 2Cell 3 — an output:
<code class="language-python">mo.md(f"**x** is {x} and **y** is {y}")The magic moment
Changex = 10tox = 20. Watch cells 2 and 3re-run automatically. You did not click anything. That is reactivity.
Key concept:in marimo, a cell that reads a variable is automatically re-run when that variable changes. The graph takes care of the rest.
slide 08 of 28
The marimo CLI
marimo ships a small but powerful command-line interface. Here are the commands you will use most.
Core commands
| Command | What it does | ||
|---|---|---|---|
| <code>marimo new</code> | Create a new notebook (also supports <code>marimo new --ai "prompt"</code> for AI-bootstrapped notebooks) | ||
| <code>marimo edit [notebook.py]</code> | Open the reactive editor (creates the file if needed) | ||
| <code>marimo run notebook.py</code> | Serve the notebook as a read-only web app (no editor UI) | ||
| <code>python notebook.py</code> | Execute as a normal Python script (cells run in DAG order) | ||
| <code>marimo export html notebook.py</code> | Export the notebook to a static HTML file |
The three ways to run one file
This is marimo's signature trick — the same.pyfile runs three ways:
- Interactive:
marimo edit notebook.py - As a script:
python notebook.py - As a web app:
marimo run notebook.py
Export options
marimo export html— static HTML, great for sharing.marimo export ipynb— convert to a Jupyter notebook (for compatibility).marimo export script— a flattened Python script.
Tip:because notebooks are plain Python, you can alsoimporta notebook as a module and reuse its functions elsewhere.slide 09 of 28
Notebook Structure: Cells as Functions
Under the hood, a marimo notebook is a Python file where every cell is a function decorated with@app.cell.
What the file looks like
<code class="language-python">import marimo as mo
app = mo.App()
@app.cell
def _():
x = 10
return (x,)
@app.cell
def _(x):
y = x * 2
return (y,)
@app.cell
def _(y, mo):
mo.md(f"y is {y}")
returnWhat this buys you
- Clean diffs.Each cell is a small, named function. Git shows exactly what changed.
- Lintable and testable.It is ordinary Python —
ruff,pytest, and your editor all work. - Agent-friendly.An AI agent edits these files with standard Read/Write/Edit tools.
The return statement
Each cell returns the variables it defines so other cells can read them. marimo uses this to build the dependency graph.
Key concept:the@app.celldecorator and thereturnstatement are how marimo knows what each cell reads and writes. That is the raw material for the reactive DAG.
slide 10 of 28
How Reactivity Works
marimo's reactive execution is the heart of the whole project. Let's look under the hood.
Static analysis
When you save a notebook, marimo parses every cell with Python'sastmodule. It extracts thetop-level reads(variables used) andwrites(variables defined) in each cell. No execution is needed to discover the graph.
Building the DAG
From those reads and writes, marimo builds adirected acyclic graphbetween cells:
- Cell A writes
x. - Cell B reads
x. - So there is an edge A → B.
Deterministic order
Given a notebook file, the execution order isfully determinedby the graph topology. For independent cells, appearance order is the tiebreaker. There is no hidden execution order — the same file always runs the same way.
Re-running on change
When you edit a cell, marimo re-runs that cell andevery cell downstreamof it, in topological order. Cells that do not depend on the change are left alone.
Key concept:the notebook is a DAG, not a script. You cannot run things out of sequence because there is no manual execution order to get wrong.
slide 11 of 28
Eliminating Hidden State
Hidden state is the classic notebook bug. Here is how marimo's model eliminates it.
The Jupyter failure mode
In Jupyter, the kernel holds state between executions. A variable can remain in memory after you edit, move, or delete the cell that created it. The notebook can appear to work in the current session and fail after "Restart Kernel and Run All."
The marimo guarantee
In marimo, there is no persistent kernel state to go stale. The runtime synchronizes dependent state automatically:
- If you change a cell, everything that depends on it re-runs.
- If you delete a cell, its variables disappear — nothing lingers.
- If you rename a variable, marimo tells you if another cell still references the old name.
What this means in practice
- No more "it worked a minute ago."
- No more stale charts.
- No more debugging execution order.
The cost
This determinism comes with a discipline: you cannot rely on global mutable state or execution-order tricks. Some Jupyter patterns (like mutating a global in one cell and reading it in another) simply do not translate directly.
Key concept:marimo trades the flexibility of arbitrary execution order for the guarantee of consistency. For reproducibility, that is usually a good trade.
slide 12 of 28
Reactive UI Elements
Reactivity is not just about code — it powers marimo's interactive UI elements too.
Widgets are variables
In marimo, a UI element is a variable like any other. Create a slider:
<code class="language-python">threshold = mo.ui.slider(0, 1000, value=200, label="Minimum revenue")Now any cell that readsthreshold.valuere-runs automatically when the slider moves. No callbacks, no observe handlers.
The widget catalog
marimo ships a rich set of built-in widgets:
- Inputs:
slider,range_slider,number,text,text_area,dropdown,multiselect,checkbox,radio,switch,button,run_button - Time:
date,datetime,date_range - Files & data:
file,file_browser,code_editor,dataframe,table,data_explorer - Composites:
array,dictionary,matrix,form,batch,tabs - Charts:
altair_chart,plotly,matplotlib(with reactive selection on points, areas, and violins) - AI / specialized:
chat,microphone,refresh
Layout helpers
Usemo.hstackandmo.vstackto arrange controls side by side or stacked, keeping related widgets tidy.
Key concept:because widgets are just variables in the reactive graph, building an interactive dashboard is as simple as writing cells that read widget values.
slide 13 of 28
SQL Cells
marimo has SQL built in — no separate kernel needed.
The <code>mo.sql</code> interface
You can run SQL directly against a dataframe or a database, and the result comes back as a DataFrame:
<code class="language-python">result = mo.sql("""
SELECT DATE_TRUNC('month', order_date) AS month,
SUM(revenue) AS total_revenue
FROM df
GROUP BY 1
ORDER BY 1
""")Supported engines
marimo's SQL works withDuckDB,Polars,Pandas, and other engines. This makes it easy to mix Python and SQL in one notebook.
Why this matters
- Query a dataframe with familiar SQL instead of chained pandas calls.
- Connect to real databases for analysis.
- The result is a DataFrame, so it flows naturally into the reactive graph.
Note:this is Python-wrapped SQL, not a separate SQL kernel. If you need a SQL-first notebook with a dedicated SQL engine, a platform like Hex or a Jupyter SQL kernel is still an option.
slide 14 of 28
Charts and Visualization
marimo renders charts from the major Python plotting libraries, and its reactivity makes them interactive.
Supported libraries
- Altair— declarative, great for interactive charts.
- Plotly— rich interactive charts.
- Matplotlib— the classic, with reactive selection on points, areas, and violins as of recent versions.
Reactive selection
Because charts are part of the reactive graph, selecting points in one chart can drive other cells. For example, select a region in a scatter plot and a table below updates to show only the selected points.
A simple example
<code class="language-python">import altair as alt
chart = mo.ui.altair_chart(
alt.Chart(df).mark_point().encode(x="x", y="y")
)Nowchart.valueholds the selected points, and any cell reading it re-runs on selection.
LaTeX support
marimo renders LaTeX out of the box viamo.md(r"..."), so you can mix equations with code and charts:
<code class="language-python">mo.md(r"Energy and mass are the same thing: $$E = mc^2$$").center()Key concept:in marimo, a chart is not a static image — it is a live, reactive object that can feed its selections back into the notebook.
slide 15 of 28
The Notebook as an App
One of marimo's most distinctive features: the notebookisthe app.
<code>marimo run</code>
<code class="language-bash">marimo run notebook.pyThis serves the notebook as aread-only web app. Code cells are hidden, UI elements are exposed, and the reactive execution model keeps the app consistent as users interact with it.
No separate framework
In Jupyter's world, turning a notebook into a dashboard means rewriting it in Streamlit, Dash, or Voila — a separate codebase, a separate deployment, a separate maintenance burden.
In marimo, there is no rewrite. The notebook you explored with is the app you ship.
What the app exposes
- Interactive widgets (sliders, dropdowns, tables, forms).
- Charts and visualizations.
- Markdown and prose.
- The reactive behavior — change an input, the outputs update.
Key concept:marimo runcollapses the gap between exploration and delivery. The same file is your scratchpad and your product.slide 16 of 28
Building a Dashboard
Let's put the pieces together into a small interactive dashboard.
The pattern
- Load datain one cell.
- Add controls(sliders, dropdowns) in another.
- Filterbased on control values.
- Rendera chart and a table.
Example
<code class="language-python">import marimo as mo
import altair as alt
# Load data
df = mo.sql("SELECT * FROM sales")
# Controls
min_revenue = mo.ui.slider(0, 1000, value=200, label="Min revenue")
region = mo.ui.dropdown(["All", "EU", "US", "APAC"], value="All", label="Region")
# Filter
filtered = df
if region.value != "All":
filtered = filtered[filtered.region == region.value]
filtered = filtered[filtered.revenue >= min_revenue.value]
# Render
mo.hstack([min_revenue, region], justify="center")
mo.md(f"**{len(filtered)} rows** above {min_revenue.value}")
mo.ui.table(filtered)What happens
Drag the slider or change the dropdown, and the filter, the count, and the table all update together. No callbacks, no wiring.
Key concept:a dashboard in marimo is just a set of cells that read widget values. The reactive graph does the rest.
slide 17 of 28
Forms and User Input
For more structured input, marimo provides forms and other composite widgets.
The <code>form</code> widget
A form groups several inputs and only submits when the user clicks a button:
<code class="language-python">form = mo.ui.form(
mo.ui.text_area("Query") + mo.ui.slider(1, 10, value=3, label="Top N")
)Reading the result
form.valueisNoneuntil the form is submitted, then it holds the submitted values. This is great for search boxes, parameter panels, and anything where you do not want to re-run on every keystroke.
Other composites
array— a dynamic list of widgets.dictionary— a set of named widgets.matrix— a grid of widgets.tabs— tabbed layout.batch— run a batch of operations.
Key concept:forms let you controlwhenreactivity fires — useful when you want a deliberate "submit" step rather than live updates on every change.
slide 18 of 28
Deploying Your App
marimo runis local-first. To put an app in front of real users, you host it yourself.
Options
- Docker— containerize the notebook and serve it behind a reverse proxy.
- WASM deployment— marimo supports running notebooks in the browser via WebAssembly (Pyodide), which can be served as static files.
- Cloud platforms— host the container on any platform that runs Docker.
What you must add yourself
- Authentication—
marimo rundoes not give you auth out of the box. - HTTPS— put it behind a TLS-terminating reverse proxy (nginx, Caddy, Traefik).
- Uptime monitoring— your hosting platform's job.
A minimal Docker approach
<code class="language-dockerfile">FROM python:3.12-slim
RUN pip install marimo
COPY notebook.py .
CMD ["marimo", "run", "notebook.py", "--host", "0.0.0.0", "--port", "8080"]Key concept:marimo makes the notebook an app, but production concerns (auth, TLS, uptime) are still yours. Treat it like any web service.
slide 19 of 28
Run as a Script
Because a marimo notebook is pure Python, you can execute it as a script.
<code class="language-bash">python notebook.pyWhat happens
The cells run inDAG order— the same deterministic order the editor uses. The output is the same as running the notebook top-to-bottom on a fresh kernel.
Why this matters
- Automation.Schedule a notebook with cron or a CI pipeline.
- Reproducibility.A script run is identical to an interactive run.
- Testing.Run notebooks in CI to catch regressions.
The <code>--sandbox</code> flag
Withuv, the--sandboxflag creates an isolated environment so the notebook's dependencies are reproducible and self-contained. This is a big part of marimo's reproducibility story.
Key concept:the same file is your interactive scratchpad and your production script. No conversion step, no separate codebase.
slide 20 of 28
Use as a Module
A marimo notebook is a Python module — you can import it and reuse its functions.
Importing a notebook
<code class="language-python">import my_notebook
result = my_notebook.some_function(data)What this enables
- Code reuse.Share functions across notebooks and scripts.
- Libraries.Build a notebook that defines utilities, then import it elsewhere.
- Testing.Import a notebook in a pytest test and assert on its outputs.
The discipline
For this to work cleanly, keep your notebook's logic in functions and avoid heavy side effects at import time. A notebook that runs expensive work on import is a poor module.
Key concept:marimo blurs the line between notebook and library. A well-structured notebook is both an analysis and a reusable module.
slide 21 of 28
Git, Testing, and CI
This is where marimo's pure-Python storage really pays off.
Git-friendly diffs
A.pynotebook produces clean, readable diffs. Code review becomes possible. You can see exactly what changed in a PR.
Linting
Because it is ordinary Python,ruffand other linters work directly on your notebooks.
Testing with pytest
Import a notebook and write tests against its functions:
<code class="language-python">import my_notebook
def test_filter():
assert my_notebook.filter_data(...) == expectedCI integration
Run notebooks in CI to verify they still execute cleanly:
<code class="language-bash">python notebook.pyIf a notebook breaks, CI fails. This catches regressions before they reach anyone.
Key concept:marimo notebooks participate in the normal software engineering workflow — version control, linting, testing, and CI — because they are just Python files.
slide 22 of 28
Reproducible Environments
Reproducibility is not just about execution order — it is about the environment too.
PEP 723 inline metadata
marimo supports PEP 723, which lets you declare a notebook's dependencies right in the file:
<code class="language-python"># /// script
# requires-python = ">=3.11"
# dependencies = [
# "pandas",
# "altair",
# ]
# ///uv integration
Withuvand the--sandboxflag, marimo creates an isolated environment from that metadata. Anyone who opens the notebook gets the same dependencies.
Why this matters
- No more "it works on my machine."
- Onboarding is instant.Clone the repo, run the notebook, done.
- Reproducible research.The environment travels with the notebook.
Key concept:marimo treats the environment as part of the notebook. Dependencies are declared in the file and resolved reproducibly.
slide 23 of 28
Export and Interop
marimo does not force you to abandon the rest of the ecosystem.
Export to HTML
<code class="language-bash">marimo export html notebook.pyProduces a static HTML file — great for sharing a read-only view.
Export to Jupyter
<code class="language-bash">marimo export ipynb notebook.pyConverts to a.ipynbfor compatibility with Jupyter-based workflows.
Export to script
<code class="language-bash">marimo export script notebook.pyFlattens the notebook into a single linear Python script.
Importing from Jupyter
marimo can convert existing.ipynbfiles into marimo notebooks. The conversion handles straightforward cases well — sequential cells with clear variable dependencies. Notebooks that rely on execution-order tricks, heavy%%magics, or global state mutation need manual cleanup.
Key concept:marimo is not a walled garden. It exports to the formats you already use and imports from Jupyter, so you can migrate incrementally.
slide 24 of 28
The AI-Native Editor
marimo is built for the agentic era. Its editor is AI-native.
Built-in AI features
- TAB autocompletion— AI-assisted completions as you type.
- Error auto-fixing— marimo suggests and applies fixes for errors.
- Integrated chat— a context-aware chat that understands your notebook.
- Inline edits— AI edits cells in place.
- Next-edit prediction— the editor predicts what you will do next.
Any model, hosted or local
marimo's AI features work with any model — hosted or local — so you are not locked into a single provider.
Why this matters
Because notebooks are plain.pyfiles, the AI has full context. It can read variables, inspect outputs, and edit cells with standard tools — no special notebook parser needed.
Key concept:marimo treats AI as a first-class citizen of the notebook, not an add-on. The pure-Python format is what makes deep AI integration possible.
slide 25 of 28
marimo pair: Agents Inside the Notebook
marimo pair is marimo's most distinctive AI feature — it drops an agentinsidea running notebook session.
What it is
marimo pair is a skill that connects a coding agent (like Claude Code or Codex CLI) to a live marimo notebook. The agent gets full control over the notebook:
- Run code in an ephemeral scratchpad.
- Add and delete cells.
- Install packages.
- Inspect the notebook's in-memory variables and state.
- Read cell outputs and the dependency graph.
Quickstart
<code class="language-bash">npx skills add marimo-team/marimo-pair/marimo-pair pair with me on my_notebook.pyThe notebook as working memory
A key idea: the agent can offload state to the notebook and query it back — inspect variables, read outputs, check the graph. The notebook becomesworking memorythe agent uses without it all living in the conversation. Over long sessions, that matters a lot.
Key concept:with marimo pair, the notebook is a shared canvas for human and agent — and an executable trace of how a result was produced.
slide 26 of 28
The marimo Ecosystem
marimo is more than a single package — it has a growing ecosystem.
Official projects
- marimo— the core reactive notebook (Apache-2.0).
- marimo-education— a curated collection of marimo notebooks for teaching.
- marimo-lsp— a language server and VS Code extension.
- marimo-agents— drop agents inside running marimo notebook sessions.
- marimo-jupyter— integrate marimo notebooks into JupyterLab and JupyterHub.
- codemirror-ai— inline completions, next-edit prediction, and prompt history.
The community
- A large, active GitHub community (tens of thousands of stars).
- A growing set of tutorials, case studies, and community notebooks.
- Production users documented by the team, including Voltus and Vodacom.
The company
Marimo Inc. is a well-funded startup (a $5M seed round in November 2024) with a clear mission: build dramatically better tools for working with data.
Key concept:marimo is not a solo project — it is a funded company with an active ecosystem, which is a good sign for long-term viability.
slide 27 of 28
marimo vs Jupyter: The Decision
Let's make the choice concrete.
When to prefer marimo
- Reproducibilityis a first-order requirement.
- You wantclean Git diffsand real code review on notebooks.
- You wantreactive dataflow— change a value, everything updates.
- You want todeploy notebooks as appswithout a rewrite.
- You wantAI agentsto work directly in your notebooks.
When to prefer Jupyter
- You need theecosystem— thousands of extensions, kernels for R/Julia/Scala.
- Every tutorial you rely on ships as
.ipynb. - You needmulti-language kernels.
- You are deeply invested in theJupyter estateand its agent integrations.
The honest middle ground
Many teams useboth— marimo for reproducible, app-ready work and Jupyter for ecosystem-dependent tasks. The two are not mutually exclusive; marimo even exports to and imports from.ipynb.
Key concept:the question is not "which won" but "which fits this job." Pick by what hurts you more: hidden-state bugs or a smaller library of integrations.
slide 28 of 28
Where marimo Is Heading
marimo is under active, well-funded development. Here is the direction.
The trajectory
- Reactive executionis the foundation and is stable.
- AI integrationis the frontier — marimo pair, the AI editor, and agent workflows are evolving fast.
- Deploymentis maturing — WASM, Docker, and cloud hosting are getting easier.
- The ecosystemis growing — more integrations, more tutorials, more production users.
What to watch
- Agent-native workflows— notebooks as executable traces of how an AI answered a query.
- WASM deployment— running notebooks fully in the browser.
- Deeper IDE integration— the team is working on tighter VS Code and editor support.
- Enterprise features— auth, collaboration, and deployment tooling are maturing.
The big idea
marimo's thesis is that the notebook should be areproducible, Git-friendly, agent-ready, app-deployableartifact — not a fragile JSON blob with hidden state. If that thesis holds, marimo is not just a nicer notebook; it is a new way to work with data.
Final thought:the most valuable skill you can take from this course is not memorizing marimo commands — it is understandingwhyreactive execution and pure-Python storage matter. That understanding transfers to any tool you use next.
← → to move · g for contents