Reactivity
marimo reacts to your code changes: run a cell, and all other cells that reference the variables it defines are automatically run with the latest data. This keeps your code and outputs consistent, and eliminates bugs before they happen.Reactivity is one of the biggest differences between marimo and traditional notebooks like Jupyter. It eliminates hidden state and provides a deterministic execution order.
How Reactivity Works
marimo statically analyzes each cell to determine:- References: The global variables it reads but doesn’t define
- Definitions: The global variables it defines
Execution Order
The order cells are executed in is determined by the relationships between cells and their variables, not by the order of cells on the page (similar to a spreadsheet). This lets you organize your code in whatever way makes the most sense to you. For example, you can put helper functions at the bottom of your notebook.Global Variable Names Must Be Unique
marimo requires that every global variable be defined by only one cell. This lets marimo keep code and outputs consistent.Creating Local Variables
Variables prefixed with an underscore (e.g.,_x) are “local” to a cell: they can’t be read by other cells. Multiple cells can reuse the same local variable names.
Encapsulating Code in Functions
If you want most or all the variables in a cell to be temporary, encapsulate them in a function:plt, fig, and ax aren’t added to the globals.
Variable Mutations Are Not Tracked
marimo does not track mutations to objects. Mutations likemy_list.append(42) or my_object.value = 42 don’t trigger reactive re-runs of other cells.
Why Not Track Mutations?
Tracking mutations reliably is impossible in Python. Reacting to mutations could result in surprising re-runs of notebook cells. If you need to mutate a variable (such as adding a new column to a dataframe), perform the mutation in the same cell as the one that defines it:Deleting Cells Deletes Variables
In marimo, deleting a cell deletes its global variables from program memory. Cells that previously referenced these variables are automatically re-run and invalidated. This eliminates a common cause of bugs in traditional notebooks like Jupyter.Lazy Mode for Expensive Notebooks
For notebooks where cells might take a long time to run or have side-effects, you can configure the runtime to be lazy instead of automatic.Working with expensive notebooks
Working with expensive notebooks
marimo provides several tools for working with expensive notebooks:
- Configure the runtime to be lazy, marking cells as stale instead of running them automatically
- Use
mo.stop()to conditionally stop execution at runtime - Disable specific cells to prevent them from running
Disabling Cells
You can disable cells to block them and their dependents from running. This is useful when you want to edit one part of a notebook without triggering automatic execution of expensive dependent cells. When you re-enable a cell, if any of the cell’s ancestors ran while it was disabled, marimo will automatically run it.Visualizing the Dependency Graph
marimo provides several tools to help you understand and navigate the dependency graph:Graph View
Visualize the complete dependency graph of your notebook
Minimap
See a bird’s-eye view of your notebook structure
Reference Highlighting
Automatically highlights related cells as you navigate
Runtime Configuration
Through the notebook settings menu, you can configure:- Autorun on startup: Whether to run cells automatically when opening the notebook
- Autorun on cell execution: Whether to run dependent cells automatically
- Module autoreloader: Automatically reload imported modules when they change
- Lazy execution: Mark cells as stale instead of running them automatically