marimo

docs.marimo.io
Developer Tools

Explore data and build apps seamlessly with marimo, a next-generation Python notebook.

llms.txt

marimo is an open-source reactive Python notebook: run a cell or interact with a UI element, and marimo automatically runs dependent cells (or marks them as stale), keeping code and outputs consistent and preventing bugs before they happen. Every marimo notebook is stored as pure Python (Git-friendly), executable as a script, and deployable as an app; while stored as Python, marimo notebooks also have native support for SQL.

Get started instantly with molab, our free online notebook. Or get started locally by installing marimo with your favorite package manager:

install with pipinstall with uvinstall with conda

[](#__codelineno-0-1)pip install marimo && marimo tutorial intro

[](#__codelineno-1-1)uv add marimo && uv run marimo tutorial intro

[](#__codelineno-2-1)conda install -c conda-forge marimo && marimo tutorial intro

Developer experience is core to marimo, with an emphasis on reproducibility, maintainability, composability, and shareability.

Highlights

A reactive programming environment

marimo guarantees your notebook code, outputs, and program state are consistent. This solves many problems associated with traditional notebooks like Jupyter.

A reactive programming environment. Run a cell and marimo reacts by automatically running the cells that reference its variables, eliminating the error-prone task of manually re-running cells. Delete a cell and marimo scrubs its variables from program memory, eliminating hidden state.

Compatible with expensive notebooks. marimo lets you configure the runtime to be lazy, marking affected cells as stale instead of automatically running them. This gives you guarantees on program state while preventing accidental execution of expensive cells.

Synchronized UI elements. Interact with UI elements like sliders, dropdowns, dataframe transformers, and chat interfaces, and the cells that use them are automatically re-run with their latest values.

Interactive dataframes. Page through, search, filter, and sort millions of rows blazingly fast, no code required.

Generate cells with data-aware AI. Collaborate on marimo notebooks with your favorite agent, such as Claude Code, Codex, or OpenCode, using marimo pair. Or, generate code in the marimo editor with an AI assistant that is highly specialized for working with data, with context about your variables in memory. Customize the system prompt, bring your own API keys, or use local models.

Query data with SQL. Build SQL queries that depend on Python values and execute them against dataframes, databases, lakehouses, CSVs, Google Sheets, or anything else using our built-in SQL engine, which returns the result as a Python dataframe.

Your notebooks are still pure Python, even if they use SQL.

Dynamic markdown. Use markdown parametrized by Python variables to tell dynamic stories that depend on Python data.

Built-in package management. marimo has built-in support for all major package managers, letting you install packages on import. marimo can even serialize package requirements in notebook files, and auto install them in isolated venv sandboxes.

Deterministic execution order. Notebooks are executed in a deterministic order, based on variable references instead of cells' positions on the page. Organize your notebooks to best fit the stories you'd like to tell.

Performant runtime. marimo runs only those cells that need to be run by statically analyzing your code.

Batteries-included. marimo comes with GitHub Copilot, AI assistants, Ruff code formatting, HTML export, fast code completion, a VS Code extension, an interactive dataframe viewer, and many more quality-of-life features.

Quickstart

The marimo concepts playlist on our YouTube channel gives an overview of many features.

Installation. In a terminal, run

[](#__codelineno-3-1)pip install marimo # or conda install -c conda-forge marimo [](#__codelineno-3-2)marimo tutorial intro

To install with additional dependencies that unlock SQL cells, AI completion, and more, run

[](#__codelineno-4-1)pip install marimo[recommended]

Create notebooks.

Create or edit notebooks with

Run apps. Run your notebook as a web app. By default, the Python source code is not sent to the browser, so it stays hidden and uneditable:

[](#__codelineno-6-1)marimo run your_notebook.py

Execute as scripts. Execute a notebook as a script at the command line:

Automatically convert Jupyter notebooks. Automatically convert Jupyter notebooks to marimo notebooks with the CLI

[](#__codelineno-8-1)marimo convert your_notebook.ipynb > your_notebook.py

or use our web interface.

Tutorials. List all tutorials:

Share cloud-based notebooks. Use molab, a cloud-based marimo notebook service similar to Google Colab, to create and share notebook links.

Questions?

See our FAQ.

Learn more

marimo is easy to get started with, with lots of room for power users. For example, here's an embedding visualizer made in marimo (try the notebook live on molab!):

Check out our guides, usage examples, and our gallery to learn more.

Contributing

We appreciate all contributions! You don't need to be an expert to help out. Please see CONTRIBUTING.md for more details on how to get started.

Questions? Reach out to us on Discord.

We're building a community. Come hang out with us!

A NumFOCUS affiliated project. marimo is a core part of the broader Python ecosystem and is a member of the NumFOCUS community, which includes projects such as NumPy, SciPy, and Matplotlib.

Inspiration ✨

marimo is a reinvention of the Python notebook as a reproducible, interactive, and shareable Python program, instead of an error-prone JSON scratchpad.

We believe that the tools we use shape the way we think — better tools, for better minds. With marimo, we hope to provide the Python community with a better programming environment to do research and communicate it; to experiment with code and share it; to learn computational science and teach it.

Our inspiration comes from many places and projects, especially Pluto.jl, ObservableHQ, and Bret Victor's essays. marimo is part of a greater movement toward reactive dataflow programming. From IPyflow, streamlit, TensorFlow, PyTorch, JAX, and React, the ideas of functional, declarative, and reactive programming are transforming a broad range of tools for the better.

Finally, we would like to acknowledge Bennet Meyers and David Chassin for believing in marimo from the very beginning: this work was supported in part by U.S. DOE Office of Critical Minerals and Energy Innovation (CMEI) Integrated Energy Systems Office (IESO), Agreement 34368.

GuideDescription
InstallationInstalling marimo
QuickstartCreate notebooks, run apps, and more from the marimo command-line
Key ConceptsA tour of key features and concepts

These guides cover marimo's core concepts.

Learn by doing!

Prefer a hands-on learning experience? marimo comes packaged with interactive tutorials that you can launch with marimo tutorial at the command line.

GuideDescription
Running cellsUnderstanding how marimo runs cells
Interactive elementsUsing interactive UI elements
Visualizing outputsCreating markdown, plots, and other visual outputs
Migrating from JupyterTips for transitioning from Jupyter
Expensive notebooksTips for working with expensive notebooks
Understanding errorsUnderstanding marimo's constraints on notebook code
Lint rulesComprehensive linting system and rule reference
Working with dataUsing SQL cells, no-code dataframe, and reactive plots
Package managementInlining dependencies in notebook files and other package management guides
Generate with AIGenerate notebooks with AI
Editor featuresView variables, dataframe schemas, docstrings, and more
Using your own editorEdit notebooks in your own editor and stream changes back to the browser
AppsRunning notebooks as apps
ScriptsRunning notebooks as scripts
Reusing functions and classesImporting functions and classes defined in marimo notebooks
TestsRunning unit tests in notebooks
Export to other formatsExport notebooks to HTML, PDF, ipynb, scripts, and more
Run and share in the cloud with molabShare cloud-hosted notebooks for free, preview from GitHub, embed in webpages
Publish to the webPublish notebooks to molab, embed in webpages, to/from GitHub, and more
Deploy notebook servers or appsDeploy notebook servers (JupyterHub, Kubernetes) or read-only apps
WebAssembly notebooksRun notebooks entirely in the browser with WebAssembly
ConfigurationConfigure various settings
Coming from other toolsTransitioning from Jupyter and other tools
Extending marimoRich displays of objects, custom UI plugins
State managementAdvanced: mutable reactive state
Best practicesBest practices to help you get the most out of marimo
DebuggingInteractive debugging with pdb, debugpy, and AI assistance
TroubleshootingTroubleshooting notebooks

Get inspired at our gallery!

For inspirational examples, including embedding-driven data labelers, Stanford-scientist authored tutorials, and more, check out our public gallery.

Running cells

Visual Outputs

Writing markdown

Working with data

Dataframes

marimo is designed for working with dataframes. Here are a few examples; see the dataframes guide for details.

SQL

Here are some basic examples, see the SQL guide for more details.

Plots

See the plotting guide for a full overview.

Progress bars and status elements

Layouts

Input elements

Basic input elements

marimo has a large library of interactive UI elements, which you can use without callbacks — just make sure to assign elements to global variables. See the API reference for a full list, and the interactivity guide for rules governing how UI elements work.

Composite input elements

Composite input elements let you create a single UI element from multiple other UI elements.

  • connect interactive inputs like sliders, dropdowns, and tables to Python,
  • express yourself with dynamically created markdown,
  • layout information with tabs or grids,
  • output media like images and audio,
  • and more!
markdownWrite markdown with mo.md
inputsConnect sliders, dropdowns, tables, and more to Python
layoutsCustomize outputs with accordions, tabs, stacks, and more
plottingOutput interactive plots
mediaOutput media like images, audio, PDFs, and plain text
diagramsFlow charts, graphs, statistic cards, and more
statusDisplay progress indicators
outputsModify cell outputs, redirect console output
control_flowControl how cells execute
htmlManipulate HTML objects
query_paramsAccess and set query parameters with mo.query_params
cli_argsAccess command-line arguments with mo.cli_args
cachingCache expensive computations in memory or on disk
stateSynchronize multiple UI elements with mo.state
appEmbed notebooks in other notebooks
cellRun cells defined in another notebook
watchReactively respond to file changes on disk
miscellaneousMiscellaneous utilities
  • marimo tutorial intro

Example usage:

  • marimo edit create or edit notebooks
  • marimo edit notebook.py create or edit a notebook called notebook.py
  • marimo run notebook.py run a notebook as a read-only app
  • marimo tutorial --help list tutorials

Usage:

[](#__codelineno-0-1)marimo [OPTIONS] COMMAND [ARGS]...

Options:

NameTypeDescriptionDefault
--versionbooleanShow the version and exit.False
-l, --log-levelchoice (DEBUGINFOWARN
-q, --quietbooleanSuppress standard out.False
-y, --yesbooleanAutomatic yes to prompts, running non-interactively.False
-d, --development-modebooleanRun in development mode; enables debug logs and server autoreload.False
-h, --helpbooleanShow this message and exit.False

marimo check

Check and format marimo files.

Usage:

[](#__codelineno-1-1)marimo check [OPTIONS] [FILES]...

Options:

NameTypeDescriptionDefault
--fixbooleanWhether to in place update files.False
--strictbooleanWhether warnings return a non-zero exit code.False
-v, --verbose / -q, --quietbooleanWhether to print detailed messages.True
--unsafe-fixesbooleanEnable fixes that may change code behavior (e.g., removing empty cells).False
--ignore-scriptsbooleanIgnore files that are not recognizable as marimo notebooks.False
--formatchoice (fulljson)Output format for diagnostics.
--selecttextComma-separated rule codes/prefixes to enable, replacing config. e.g. --select MB,MR001None
--ignoretextComma-separated rule codes/prefixes to ignore. e.g. --ignore MF004,MF007None
-h, --helpbooleanShow this message and exit.False

marimo config

Various commands for the marimo config.

Usage:

[](#__codelineno-2-1)marimo config [OPTIONS] COMMAND [ARGS]...

Options:

NameTypeDescriptionDefault
-h, --helpbooleanShow this message and exit.False

marimo config describe

Describe the marimo config.

Usage:

[](#__codelineno-3-1)marimo config describe [OPTIONS]

Options:

NameTypeDescriptionDefault
-h, --helpbooleanShow this message and exit.False

marimo config show

Show the marimo config.

Usage:

[](#__codelineno-4-1)marimo config show [OPTIONS]

Options:

NameTypeDescriptionDefault
-h, --helpbooleanShow this message and exit.False

marimo convert

Convert a Jupyter notebook, Markdown file, or Python script to a marimo notebook.

Supported input formats: - .ipynb (local or GitHub-hosted) - .md files with {python} code fences - .py scripts in py:percent format

Behavior: - Jupyter notebooks: outputs are stripped.

  • Markdown files: only {python} fenced code blocks are converted.

Example:

- Python scripts: - If already a valid marimo notebook, no conversion is performed. - Otherwise, marimo attempts to convert using py:percent formatting, preserving top-level comments and docstrings.

Example usage:

marimo convert your_nb.ipynb -o your_nb.py

or

marimo convert your_nb.md -o your_nb.py

or

marimo convert script.py -o your_nb.py

You can also pass global flags to the main marimo command. For example, use -q to suppress output or -y to automatically accept all prompts of the command.

marimo -q -y convert script.py -o your_nb.py

After conversion:

Note: Since marimo's reactive execution differs from traditional notebooks, you may need to refactor code that mutates variables across cells (e.g., modifying a dataframe in multiple cells), which can lead to unexpected behavior.

Usage:

[](#__codelineno-6-1)marimo convert [OPTIONS] FILENAME

Options:

NameTypeDescriptionDefault
-o, --outputpathOutput file to save the converted notebook to. If not provided, the converted notebook will be printed to stdout.None
-h, --helpbooleanShow this message and exit.False

marimo edit

Create or edit notebooks. If NAME is a url, the notebook will be downloaded to a temporary file. * marimo edit Start the marimo notebook server * marimo edit notebook.py Create or edit notebook.py

Usage:

[](#__codelineno-7-1)marimo edit [OPTIONS] [NAME] [ARGS]...

Options:

NameTypeDescriptionDefault
-p, --portintegerPort to attach to.None
--hosttextHost to attach to.127.0.0.1
--proxytextAddress of reverse proxy.None
--headlessbooleanDon't launch a browser.False
--token / --no-tokenbooleanUse a token for authentication. This enables session-based authentication. A random token will be generated if --token-password is not set. If --no-token is set, session-based authentication will not be used.True
--token-passwordtextUse a specific token for authentication. This enables session-based authentication. A random token will be generated if not set.None
--token-password-filetextPath to file containing token password, or '-' for stdin. Mutually exclusive with --token-password.None
--base-urltextBase URL for the server. Should start with a /.``
--allow-originstextAllowed origins for CORS. Can be repeated. Use * for all origins.None
--skip-update-checkbooleanDon't check if a new version of marimo is available for download.False
--sandbox / --no-sandboxbooleanRun the notebook in an isolated environment, with dependencies tracked via PEP 723 inline metadata. If already declared, dependencies will install automatically. Requires uv.None
--trusted / --untrustedbooleanRun notebooks hosted remotely on the host machine; if --untrusted, runs marimo in a Docker container.None
--watchbooleanWatch the file for changes and reload the code when saved in another editor.False
--skew-protection / --no-skew-protectionbooleanEnable skew protection middleware to prevent version mismatch issues.True
--timeoutfloatEnable a global timeout to shut down the server after specified number of minutes of no connectionNone
--session-ttlintegerSeconds to wait before closing a session on websocket disconnect. If None is provided, sessions are not automatically closed.None
-h, --helpbooleanShow this message and exit.False

marimo env

Print out environment information for debugging purposes.

Usage:

Options:

NameTypeDescriptionDefault
-h, --helpbooleanShow this message and exit.False

marimo export

Export a notebook to various formats.

Usage:

[](#__codelineno-9-1)marimo export [OPTIONS] COMMAND [ARGS]...

Options:

NameTypeDescriptionDefault
-h, --helpbooleanShow this message and exit.False

marimo export html

Run a notebook and export it as an HTML file.

Example:

marimo export html notebook.py -o notebook.html

Optionally pass CLI args to the notebook:

marimo export html notebook.py -o notebook.html -- -arg1 foo -arg2 bar

Usage:

[](#__codelineno-10-1)marimo export html [OPTIONS] NAME [ARGS]...

Options:

NameTypeDescriptionDefault
--include-code / --no-include-codebooleanInclude notebook code in the exported HTML file.True
--watch / --no-watchbooleanWatch notebook for changes and regenerate the output on modification. If watchdog is installed, it will be used to watch the file. Otherwise, file watcher will poll the file every 1s.False
-o, --outputpathOutput file to save the HTML to. If not provided, the HTML will be printed to stdout.None
--sandbox / --no-sandboxbooleanRun the command in an isolated virtual environment using uv run --isolated. Requires uv.None
-f, --forcebooleanForce overwrite of the output file if it already exists.False
-h, --helpbooleanShow this message and exit.False

marimo export html-wasm

Export a notebook as a WASM-powered standalone HTML file.

Example:

marimo export html-wasm notebook.py -o notebook.wasm.html

The exported HTML file will run the notebook using WebAssembly, making it completely self-contained and executable in the browser. This lets you share interactive notebooks on the web without setting up infrastructure to run Python code.

The exported notebook runs using Pyodide, which supports most but not all Python packages. To learn more, see the Pyodide documentation.

In order for this file to be able to run, it must be served over HTTP, and cannot be opened directly from the file system (e.g. file://).

Usage:

[](#__codelineno-11-1)marimo export html-wasm [OPTIONS] NAME [ARGS]...

Options:

NameTypeDescriptionDefault
-o, --outputpathOutput directory to save the HTML to._required
--modechoice (editrun)Whether the notebook code should be editable or readonly.
--watch / --no-watchbooleanWhether to watch the original file and export upon changeFalse
--show-code / --no-show-codebooleanWhether to show code by default in the exported HTML file; only relevant for run mode.False
--include-cloudflare / --no-include-cloudflarebooleanWhether to include Cloudflare Worker configuration files (index.js and wrangler.jsonc) for easy deployment.False
--sandbox / --no-sandboxbooleanRun the command in an isolated virtual environment using uv run --isolated. Requires uv.None
-f, --forcebooleanForce overwrite of the output file if it already exists.False
--execute / --no-executebooleanExecute the notebook before exporting and embed outputs as a preview. Runs in an isolated environment pinned to WASM-compatible packages when possible.False
-h, --helpbooleanShow this message and exit.False

marimo export ipynb

Export a marimo notebook as a Jupyter notebook in topological order.

Example:

marimo export ipynb notebook.py -o notebook.ipynb

Watch for changes and regenerate the script on modification:

marimo export ipynb notebook.py -o notebook.ipynb --watch

Optionally pass CLI args to the notebook:

marimo export ipynb notebook.py -o notebook.ipynb --include-outputs -- -arg1 foo -arg2 bar

Requires nbformat to be installed.

Usage:

[](#__codelineno-12-1)marimo export ipynb [OPTIONS] NAME [ARGS]...

Options:

NameTypeDescriptionDefault
--sortchoice (top-downtopological)Sort cells top-down or in topological order.
--watch / --no-watchbooleanWatch notebook for changes and regenerate the output on modification. If watchdog is installed, it will be used to watch the file. Otherwise, file watcher will poll the file every 1s.False
-o, --outputpathOutput file to save the ipynb file to. If not provided, the ipynb contents will be printed to stdout.None
--include-outputs / --no-include-outputsbooleanRun the notebook and include outputs in the exported ipynb file.False
--sandbox / --no-sandboxbooleanRun the command in an isolated virtual environment using uv run --isolated. Requires uv.None
-f, --forcebooleanForce overwrite of the output file if it already exists.False
-h, --helpbooleanShow this message and exit.False

marimo export md

Export a marimo notebook as a code fenced Markdown file.

Example:

marimo export md notebook.py -o notebook.md

Watch for changes and regenerate the script on modification:

marimo export md notebook.py -o notebook.md --watch

Usage:

[](#__codelineno-13-1)marimo export md [OPTIONS] NAME

Options:

NameTypeDescriptionDefault
--watch / --no-watchbooleanWatch notebook for changes and regenerate the output on modification. If watchdog is installed, it will be used to watch the file. Otherwise, file watcher will poll the file every 1s.False
-o, --outputpathOutput file to save the markdown to. If not provided, markdown will be printed to stdout.None
--sandbox / --no-sandboxbooleanRun the command in an isolated virtual environment using uv run --isolated. Requires uv.None
-f, --forcebooleanForce overwrite of the output file if it already exists.False
-h, --helpbooleanShow this message and exit.False

marimo export pdf

Export a marimo notebook as a PDF file.

Example:

marimo export pdf notebook.py -o notebook.pdf

Optionally pass CLI args to the notebook:

marimo export pdf notebook.py -o notebook.pdf -- -arg1 foo -arg2 bar

Export PDFs in a specific format such as slides:

marimo export pdf notebook.py -o notebook.pdf --as=slides

Requires nbformat and nbconvert to be installed.

Usage:

[](#__codelineno-14-1)marimo export pdf [OPTIONS] NAME [ARGS]...

Options:

NameTypeDescriptionDefault
--include-outputs / --no-include-outputsbooleanRun the notebook and include outputs in the exported PDF file.True
--include-inputs / --no-include-inputsbooleanInclude code cell inputs in the exported PDF file.True
--webpdf / --no-webpdfbooleanUse nbconvert's WebPDF exporter (Chromium). If disabled, marimo will try standard PDF export (pandoc + TeX) first and fall back to WebPDF.True
--rasterize-outputs / --no-rasterize-outputsbooleanRasterize marimo widget HTML and Vega outputs to PNG fallbacks before PDF conversion (enabled by default).True
--raster-scalefloat range (between 1.0 and 4.0)Scale factor for rasterized output screenshots.4.0
--raster-serverchoice (staticlive)Server mode used for raster capture. Use 'static' (default) for faster captures, or 'live' if outputs require a live Python connection. For --as=slides, 'live' is recommended.
--aschoice (documentslides)PDF export preset. Use slides for reveal.js slide-style output. If omitted, marimo exports as a standard document PDF.
--watch / --no-watchbooleanWatch notebook for changes and regenerate the output on modification. If watchdog is installed, it will be used to watch the file. Otherwise, file watcher will poll the file every 1s.False
-o, --outputpathOutput PDF file to save to._required
--sandbox / --no-sandboxbooleanRun the command in an isolated virtual environment using uv run --isolated. Requires uv.None
-f, --forcebooleanForce overwrite of the output file if it already exists.False
-h, --helpbooleanShow this message and exit.False

marimo export script

Export a marimo notebook as a flat script, in topological order.

Example:

marimo export script notebook.py -o notebook.script.py

Watch for changes and regenerate the script on modification:

marimo export script notebook.py -o notebook.script.py --watch

Usage:

[](#__codelineno-15-1)marimo export script [OPTIONS] NAME

Options:

NameTypeDescriptionDefault
--watch / --no-watchbooleanWatch notebook for changes and regenerate the output on modification. If watchdog is installed, it will be used to watch the file. Otherwise, file watcher will poll the file every 1s.False
-o, --outputpathOutput file to save the script to. If not provided, the script will be printed to stdout.None
--sandbox / --no-sandboxbooleanRun the command in an isolated virtual environment using uv run --isolated. Requires uv.None
-f, --forcebooleanForce overwrite of the output file if it already exists.False
-h, --helpbooleanShow this message and exit.False

marimo export session

Execute a notebook or directory of notebooks and export session snapshots.

Usage:

[](#__codelineno-16-1)marimo export session [OPTIONS] NAME [ARGS]...

Options:

NameTypeDescriptionDefault
--sandbox / --no-sandboxbooleanRun the command in an isolated virtual environment using uv run --isolated. Requires uv.None
--force-overwrite / --no-force-overwritebooleanOverwrite all existing session snapshots, even if they are already up-to-date.False
--continue-on-error / --no-continue-on-errorbooleanContinue processing other notebooks if one notebook fails.True
-h, --helpbooleanShow this message and exit.False

marimo export thumbnail

Generate OpenGraph thumbnails for notebooks.

Usage:

[](#__codelineno-17-1)marimo export thumbnail [OPTIONS] NAME [ARGS]...

Options:

NameTypeDescriptionDefault
--widthintegerViewport width for the screenshot.1200
--heightintegerViewport height for the screenshot.630
--scaleinteger range (between 1 and 4)Device scale factor for screenshots. Output resolution will be width*scale x height*scale.2
--timeout-msintegerAdditional time to wait after page load before screenshot.1500
--outputpathOutput filename. If omitted, writes to <notebook_dir>/__marimo__/assets/<notebook_stem>/opengraph.png.None
--overwrite / --no-overwritebooleanOverwrite existing thumbnails.False
--include-code / --no-include-codebooleanWhether to include code in the rendered HTML before screenshot.False
--execute / --no-executebooleanExecute notebooks and include their outputs in thumbnails. In --no-execute mode (default), thumbnails are generated from notebook structure without running code (and will not include outputs).False
--sandbox / --no-sandboxbooleanRender notebooks in an isolated environment, with dependencies tracked via PEP 723 inline metadata. If already declared, dependencies will install automatically. Requires uv. Only applies when --execute is used.None
--continue-on-error / --fail-fastbooleanContinue processing other notebooks if one notebook fails.True
-h, --helpbooleanShow this message and exit.False

marimo new

Create an empty notebook, or generate from a prompt with AI

  • marimo new Create an empty notebook
  • marimo new prompt.txt Generate a notebook from a prompt in a file.
  • marimo new "Plot an interactive 3D surface with matplotlib." Generate a notebook from a prompt.

Visit https://marimo.app/ai for more prompt examples.

Usage:

[](#__codelineno-18-1)marimo new [OPTIONS] [PROMPT]

Options:

NameTypeDescriptionDefault
-p, --portintegerPort to attach to.None
--hosttextHost to attach to.127.0.0.1
--proxytextAddress of reverse proxy.None
--headlessbooleanDon't launch a browser.False
--token / --no-tokenbooleanUse a token for authentication. This enables session-based authentication. A random token will be generated if --token-password is not set. If --no-token is set, session-based authentication will not be used.True
--token-passwordtextUse a specific token for authentication. This enables session-based authentication. A random token will be generated if not set.None
--token-password-filetextPath to file containing token password, or '-' for stdin. Mutually exclusive with --token-password.None
--base-urltextBase URL for the server. Should start with a /.``
--sandbox / --no-sandboxbooleanRun the notebook in an isolated environment, with dependencies tracked via PEP 723 inline metadata. If already declared, dependencies will install automatically. Requires uv.None
--skew-protection / --no-skew-protectionbooleanEnable skew protection middleware to prevent version mismatch issues.True
--timeoutfloatEnable a global timeout to shut down the server after specified number of minutes of no connectionNone
-h, --helpbooleanShow this message and exit.False

marimo pair

Commands for pair programming with AI.

Usage:

[](#__codelineno-19-1)marimo pair [OPTIONS] COMMAND [ARGS]...

Options:

NameTypeDescriptionDefault
-h, --helpbooleanShow this message and exit.False

marimo pair prompt

Generate a prompt for pair programming on a running marimo notebook.

Usage:

[](#__codelineno-20-1)marimo pair prompt [OPTIONS]

Options:

NameTypeDescriptionDefault
--urltextURL of the running marimo kernel._required
--claudebooleanValidate that the marimo-pair Claude Code skill is installed.False
--codexbooleanValidate that the marimo-pair Codex skill is installed.False
--opencodebooleanValidate that the marimo-pair opencode skill is installed.False
--with-tokenbooleanPrompt for an auth token and store it in a temp file.False
-h, --helpbooleanShow this message and exit.False

marimo recover

Recover a marimo notebook from a JSON file.

When the frontend loses its connection to the kernel, marimo auto-saves unsaved cell changes to a JSON recovery file. Use this command to convert that JSON file back into a marimo notebook (.py), printing the recovered source to stdout.

Example:

marimo recover notebook_recovery.json > recovered_notebook.py

Usage:

[](#__codelineno-21-1)marimo recover [OPTIONS] NAME

Options:

NameTypeDescriptionDefault
-h, --helpbooleanShow this message and exit.False

marimo run

Run a notebook as an app in read-only mode.

If NAME is a url, the notebook will be downloaded to a temporary file.

Example:

marimo run notebook.py marimo run folder another_folder marimo run app.py -- --arg value

Usage:

[](#__codelineno-22-1)marimo run [OPTIONS] NAME [ARGS]...

Options:

NameTypeDescriptionDefault
-p, --portintegerPort to attach to.None
--hosttextHost to attach to.127.0.0.1
--proxytextAddress of reverse proxy.None
--headlessbooleanDon't launch a browser.False
--token / --no-tokenbooleanUse a token for authentication. This enables session-based authentication. A random token will be generated if --token-password is not set. If --no-token is set, session-based authentication will not be used.False
--token-passwordtextUse a specific token for authentication. This enables session-based authentication. A random token will be generated if not set.None
--token-password-filetextPath to file containing token password, or '-' for stdin. Mutually exclusive with --token-password.None
--include-codebooleanSend notebook source code to the client. By default, code is not sent to the client and cannot be viewed in the browser.False
--session-ttlintegerSeconds to wait before closing a session on websocket disconnect.120
--watchbooleanWatch the file for changes and reload the app. If watchdog is installed, it will be used to watch the file. Otherwise, file watcher will poll the file every 1s.False
--skew-protection / --no-skew-protectionbooleanEnable skew protection middleware to prevent version mismatch issues.True
--base-urltextBase URL for the server. Should start with a /.``
--allow-originstextAllowed origins for CORS. Can be repeated.None
--redirect-console-to-browserbooleanRedirect console logs to the browser console.False
--sandbox / --no-sandboxbooleanRun the notebook in an isolated environment, with dependencies tracked via PEP 723 inline metadata. If already declared, dependencies will install automatically. Requires uv.None
--check / --no-checkbooleanDisable a static check of the notebook before running.True
--trusted / --untrustedbooleanRun notebooks hosted remotely on the host machine; if --untrusted, runs marimo in a Docker container.None
--show-tracebacks / --no-show-tracebacksbooleanShow detailed error tracebacks in a modal when exceptions occur.None
-h, --helpbooleanShow this message and exit.False

marimo shell-completion

Install shell completions for marimo. Supports bash, zsh, and fish.

Usage:

[](#__codelineno-23-1)marimo shell-completion [OPTIONS]

Options:

NameTypeDescriptionDefault
-h, --helpbooleanShow this message and exit.False

marimo tutorial

Open a tutorial.

marimo is a powerful library for making reactive notebooks and apps. To get the most out of marimo, get started with a few tutorials, starting with the intro:

Recommended sequence:

- intro - dataflow - ui - markdown - plots - sql - layout - fileformat - external-dependencies - markdown-format - for-jupyter-users

Usage:

[](#__codelineno-24-1)marimo tutorial [OPTIONS] {intro|dataflow|ui|markdown|plots|sql|layout|filefor [](#__codelineno-24-2) mat|external-dependencies|markdown-format|for-jupyter-users}

Options:

NameTypeDescriptionDefault
-p, --portintegerPort to attach to.None
--hosttextHost to attach to.127.0.0.1
--proxytextAddress of reverse proxy.None
--headlessbooleanDon't launch a browser.False
--token / --no-tokenbooleanUse a token for authentication. This enables session-based authentication. A random token will be generated if --token-password is not set. If --no-token is set, session-based authentication will not be used.True
--token-passwordtextUse a specific token for authentication. This enables session-based authentication. A random token will be generated if not set.None
--token-password-filetextPath to file containing token password, or '-' for stdin. Mutually exclusive with --token-password.None
--skew-protection / --no-skew-protectionbooleanEnable skew protection middleware to prevent version mismatch issues.True
-h, --helpbooleanShow this message and exit.False

How is marimo different from Jupyter?

marimo is a reinvention of the Python notebook as a reproducible, interactive, and shareable Python program that can be executed as scripts or deployed as interactive web apps.

Consistent state. In marimo, your notebook code, outputs, and program state are guaranteed to be consistent. Run a cell and marimo reacts by automatically running the cells that reference its variables. Delete a cell and marimo scrubs its variables from program memory, eliminating hidden state.

Built-in interactivity. marimo also comes with UI elements like sliders, a dataframe transformer, and interactive plots that are automatically synchronized with Python. Interact with an element and the cells that use it are automatically re-run with its latest value.

Pure Python programs. Unlike Jupyter notebooks, marimo notebooks are stored as pure Python files that can be executed as scripts, deployed as interactive web apps, and versioned easily with Git.

What problems does marimo solve?

marimo solves problems in reproducibility, maintainability, interactivity, reusability, and shareability of notebooks.

Reproducibility. In Jupyter notebooks, the code you see doesn't necessarily match the outputs on the page or the program state. If you delete a cell, its variables stay in memory, which other cells may still reference; users can execute cells in arbitrary order. This leads to widespread reproducibility issues. One study analyzed 10 million Jupyter notebooks and found that 36% of them weren't reproducible.

In contrast, marimo guarantees that your code, outputs, and program state are consistent, eliminating hidden state and making your notebook reproducible. marimo achieves this by intelligently analyzing your code and understanding the relationships between cells, and automatically re-running cells as needed.

In addition, marimo notebooks can serialize package requirements inline; marimo runs these "sandboxed" notebooks in temporary virtual environments, making them reproducible down to the packages.

Maintainability. marimo notebooks are stored as pure Python programs (.py files). This lets you version them with Git; in contrast, Jupyter notebooks are stored as JSON and require extra steps to version.

Interactivity. marimo notebooks come with UI elements that are automatically synchronized with Python (like sliders, dropdowns); eg, scrub a slider and all cells that reference it are automatically re-run with the new value. This is difficult to get working in Jupyter notebooks.

Reusability. marimo notebooks can be executed as Python scripts from the command-line (since they're stored as .py files). In contrast, this requires extra steps to do for Jupyter, such as copying and pasting the code out or using external frameworks. We also let you import symbols (functions, classes) defined in a marimo notebook into other Python programs/notebooks, something you can't easily do with Jupyter.

Shareability. Every marimo notebook can double as an interactive web app, complete with UI elements, which you can serve using the marimo run command. This isn't possible in Jupyter without substantial extra effort.

To learn more about problems with traditional notebooks, see these references [1] [2].

How is marimo.ui different from Jupyter widgets?

Unlike Jupyter widgets, marimo's interactive elements are automatically synchronized with the Python kernel: no callbacks, no observers, no manually re-running cells.

Using marimo

Is marimo a notebook or a library?

marimo is both a notebook and a library.

  • Create marimo notebooks with the editor that opens in your browser when you run marimo edit.
  • Use the marimo library (import marimo as mo) in marimo notebooks. Write markdown with mo.md(...), create stateful interactive elements with mo.ui (mo.ui.slider(...)), and more. See the docs for an API reference.

What's the difference between a marimo notebook and a marimo app?

marimo programs are notebooks, apps, or both, depending on how you use them.

There are two ways to interact with a marimo program:

  1. open it as a computational notebook with marimo edit
  2. run it as an interactive app with marimo run

All marimo programs start as notebooks, since they are created with marimo edit. Because marimo notebooks are reactive and have built-in interactive elements, many can easily be made into useful and beautiful apps by simply hiding the notebook code: this is what marimo run does.

Not every notebook needs to be run as an app — marimo notebooks are useful in and of themselves for rapidly exploring data and doing reproducible science. And not every app is improved by interacting with the notebook. In some settings, such as collaborative research, education, and technical presentations, going back and forth between the notebook view and app view (which you can do from marimo edit) can be useful!

How does marimo know what cells to run?

marimo reads each cell once to determine what global names it defines and what global names it reads. When a cell is run, marimo runs all other cells that read any of the global names it defines. A global name can refer to a variable, class, function, or import.

In other words, marimo uses static analysis to make a dataflow graph out of your cells. Each cell is a node in the graph across which global variables "flow". Whenever a cell is run, either because you changed its code or interacted with a UI element it reads, all its descendants run in turn.

Does marimo slow my code down?

No, marimo doesn't slow your code down. marimo determines the dependencies among cells by reading your code, not running or tracing it, so there's zero runtime overhead.

How do I prevent automatic execution from running expensive cells?

Reactive (automatic) execution ensures your code and outputs are always in sync, improving reproducibility by eliminating hidden state and out-of-order execution; marimo also takes care to run only the minimal set of cells needed to keep your notebook up to date. But when some cells take a long time to run, it's understandable to be concerned that automatic execution will kick off expensive cells before you're ready to run them.

Here are some tips to avoid accidental execution of expensive cells:

  • Disable expensive cells. When a cell is disabled, it and its descendants are blocked from running.
  • Wrap UI elements in a form.
  • Use mo.stop to conditionally stop execution of a cell and its descendants.
  • Decorate functions with marimo's mo.cache to cache expensive intermediate computations.
  • Use mo.persistent_cache to cache variables to disk; on re-run, marimo will read values from disk instead of recalculating them as long as the cell is not stale.
  • Disable automatic execution in the runtime configuration.

How do I disable automatic execution?

You can disable automatic execution through the notebook runtime settings; see the guide on runtime configuration.

When automatic execution is disabled, marimo still gives you guarantees on your notebook state and automatically marks cells as stale when appropriate.

How do I use sliders and other interactive elements?

Interactive UI elements like sliders are available in marimo.ui.

  • Assign the UI element to a global variable (slider = mo.ui.slider(0, 100))
  • Include it in the last expression of a cell to display it (slider or mo.md(f"Choose a value: {slider}"))
  • Read its current value in another cell via its value attribute (slider.value)

When a UI element bound to a global variable is interacted with, all cells referencing the global variable are run automatically.

If you have many UI elements or don't know the elements you'll create until runtime, use marimo.ui.array and marimo.ui.dictionary to create UI elements that wrap other UI elements (sliders = mo.ui.array([slider(1, 100) for _ in range(n_sliders)])).

All this and more is explained in the UI tutorial. Run it with

at the command line.

How do I add a submit button to UI elements?

Use the form method to add a submit button to a UI element. For example,

[](#__codelineno-1-1)form = marimo.ui.text_area().form()

When wrapped in a form, the text area's value will only be sent to Python when you click the submit button. Access the last submitted value of the text area with form.value.

How do I write markdown?

Import marimo (as mo) in a notebook, and use the mo.md function. Learn more in the outputs guide or by running marimo tutorial markdown.

How do I display plots?

Include plots in the last expression of a cell to display them, just like all other outputs. If you're using matplotlib, you can display the Figure object (get the current figure with plt.gcf()). For examples, run the plots tutorial:

Also see the plotting API reference.

How do I prevent matplotlib plots from being cut off?

If your legend or axes labels are cut off, try calling plt.tight_layout() before outputting your plot:

[](#__codelineno-3-1)import matplotlib.pyplot as plt [](#__codelineno-3-2)[](#__codelineno-3-3)plt.plot([-8, 8]) [](#__codelineno-3-4)plt.ylabel("my variable") [](#__codelineno-3-5)plt.tight_layout() [](#__codelineno-3-6)plt.gca()

How do I display interactive matplotlib plots?

Use marimo.mpl.interactive.

[](#__codelineno-4-1)fig, ax = plt.subplots() [](#__codelineno-4-2)ax.plot([1, 2]) [](#__codelineno-4-3)mo.mpl.interactive(ax)

How do I display objects in rows and columns?

Use marimo.hstack and marimo.vstack. See the layout tutorial for details:

How do I show cell code in the app view?

Use mo.show_code.

How do I create an output with a dynamic number of UI elements?

Use mo.ui.array, mo.ui.dictionary, or mo.ui.batch to create a UI element that wraps a dynamic number of other UI elements.

If you need custom formatting, use mo.ui.batch, otherwise use mo.ui.array or mo.ui.dictionary.

For usage examples, see the recipes for grouping UI elements together.

How do I let users interrupt a progress bar iteration?

To create an interruptible progress bar, run the progress bar in its own thread, and create a button that on change signals to the thread that it should exit.

Example:

[](#__codelineno-6-1)import marimo [](#__codelineno-6-2)[](#__codelineno-6-3)__generated_with = "0.20.1" [](#__codelineno-6-4)app = marimo.App() [](#__codelineno-6-5) [](#__codelineno-6-6)[](#__codelineno-6-7)@app.cell [](#__codelineno-6-8)def _(): [](#__codelineno-6-9) import marimo as mo [](#__codelineno-6-10) import time [](#__codelineno-6-11) from threading import Event [](#__codelineno-6-12) return Event, mo, time [](#__codelineno-6-13) [](#__codelineno-6-14)[](#__codelineno-6-15)@app.cell [](#__codelineno-6-16)def _(Event): [](#__codelineno-6-17) cancelled = Event() [](#__codelineno-6-18) return (cancelled,) [](#__codelineno-6-19) [](#__codelineno-6-20)[](#__codelineno-6-21)@app.cell [](#__codelineno-6-22)def _(cancelled, mo): [](#__codelineno-6-23) cancel = mo.ui.button( [](#__codelineno-6-24) label="Interrupt the progress bar", on_change=lambda _: cancelled.set() [](#__codelineno-6-25) ) [](#__codelineno-6-26) cancel [](#__codelineno-6-27) return [](#__codelineno-6-28) [](#__codelineno-6-29)[](#__codelineno-6-30)@app.cell [](#__codelineno-6-31)def _(cancelled, mo, time): [](#__codelineno-6-32) def progress(total): [](#__codelineno-6-33) with mo.status.progress_bar(total=10) as pbar: [](#__codelineno-6-34) for _ in range(10): [](#__codelineno-6-35) if cancelled.is_set(): [](#__codelineno-6-36) pbar.update( [](#__codelineno-6-37) increment=0, subtitle="The user cancelled the iteration" [](#__codelineno-6-38) ) [](#__codelineno-6-39) break [](#__codelineno-6-40) # Sleep... or anything else that releases GIL [](#__codelineno-6-41) time.sleep(0.5) [](#__codelineno-6-42) pbar.update() [](#__codelineno-6-43) [](#__codelineno-6-44) return (progress,) [](#__codelineno-6-45) [](#__codelineno-6-46)[](#__codelineno-6-47)@app.cell [](#__codelineno-6-48)def _(mo, progress): [](#__codelineno-6-49) mo.Thread(target=progress, args=(10,)).start() [](#__codelineno-6-50) return [](#__codelineno-6-51) [](#__codelineno-6-52)[](#__codelineno-6-53)if __name__ == "__main__": [](#__codelineno-6-54) app.run()

How do I restart a notebook?

To clear all program memory and restart the notebook from scratch, open the notebook menu in the top right and click "Restart kernel".

How do I reload modules?

Enable automatic reloading of modules via the runtime settings in your marimo installation's user configuration. (Click the "gear" icon in the top right of a marimo notebook).

When enabled, marimo will automatically hot-reload modified modules before executing a cell.

Why aren't my on_change/on_click handlers being called?

A UI Element's on_change (or for buttons, on_click) handlers are only called if the element is bound to a global variable. For example, this won't work

[](#__codelineno-7-1)mo.vstack([mo.ui.button(on_change=lambda _: print("I was called")) for _ in range(10)])

In such cases (when you want to output a dynamic number of UI elements), you need to use mo.ui.array, mo.ui.dictionary, or mo.ui.batch.

See the recipes for grouping UI elements together for example code.

Why are my on_change handlers in an array all referencing the last element?

Don't do this: In the below snippet, every on_change will print 9!.

[](#__codelineno-8-1)array = mo.ui.array( [](#__codelineno-8-2) [mo.ui.button(on_change=lambda value: print(i)) for i in range(10) [](#__codelineno-8-3)])

Instead, do this: Explicitly bind i to the current loop value:

[](#__codelineno-9-1)array = mo.ui.array( [](#__codelineno-9-2) [mo.ui.button(on_change=lambda value, i=i: print(i)) for i in range(10)] [](#__codelineno-9-3)) [](#__codelineno-9-4)array

This is necessary because in Python, closures are late-binding.

Why aren't my SQL brackets working?

Our "SQL" cells are really just Python under the hood to keep notebooks as pure Python scripts. By default, we use f-strings for SQL strings, which allows for parameterized SQL like SELECT * from table where value < {min}.

To escape real { / } that you don't want parameterized, use double \{\{...\}\}:

[](#__codelineno-10-1)SELECT unnest([\{\{'a': 42, 'b': 84\}\}, \{\{'a': 100, 'b': NULL\}\}]);

How does marimo treat type annotations?

Type annotations are registered as references of a cell, unless they are explicitly written as strings. This helps ensure correctness of code that depends on type annotations at runtime (e.g., Pydantic), while still providing a way to omit annotations from affecting dataflow graph.

For example, in

A is treated as a reference, used in determining the dataflow graph, but in

A isn't made a reference.

For Python 3.12+, marimo additionally implements annotation scoping.

How do I use dotenv?

The package dotenv's loadenv() function does not work out-of-the box in marimo. Instead, use dotenv.load_dotenv(dotenv.find_dotenv(usecwd=True)).

What packages can I use?

You can use any Python package. marimo cells run arbitrary Python code.

How do I use marimo on a remote server?

We recorded a video tutorial on how to use marimo on a remote server. Check it out here.

Use SSH port-forwarding to run marimo on a remote server and connect to it from a browser on your local machine. Make sure to pass the --headless flag when starting marimo on remote; on the remote machine, we also recommend using a port other than marimo's default port, such as 8080:

On the remote machine, run:

[](#__codelineno-13-1)marimo edit --headless --port 8080

or, if you want to set a custom host:

[](#__codelineno-14-1)marimo edit --headless --host 0.0.0.0 --port 8080

On local, run:

[](#__codelineno-15-1)ssh -N -L 3718:127.0.0.1:8080 REMOTE_USER@REMOTE_HOST

Then open localhost:3718 in your browser.

How do I make marimo accessible on all network interfaces?

Use --host 0.0.0.0 with marimo edit, marimo run, or marimo tutorial:

[](#__codelineno-16-1)marimo edit --host 0.0.0.0

How do I use marimo behind JupyterHub?

JupyterHub can be configured to launch marimo using the marimo-jupyter-extension.

How do I use marimo with JupyterBook?

JupyterBook makes it easy to create static websites with markdown and Jupyter notebooks.

To include a marimo notebook in a JupyterBook, you can either export your notebook to an ipynb file, or export to HTML:

  1. export to ipynb: marimo export ipynb my_notebook.py -o my_notebook.ipynb --include-outputs
  2. export to HTML: marimo export html my_notebook.py -o my_notebook.html

How do I deploy apps?

Use the marimo CLI's run command to serve a notebook as an app:

If you are running marimo inside a Docker container, you may want to run under a different host and port:

[](#__codelineno-18-1)marimo run notebook.py --host 0.0.0.0 --port 8080

Is marimo free?

Yes!

Shields

You can use our shield for opening a marimo application:


Markdown

[](#__codelineno-0-1)[![marimo](https://marimo.io/shield.svg)](https://marimo.app/l/c7h6pz)

HTML

[](#__codelineno-1-1)<a target="_blank" href="https://marimo.app/l/c7h6pz"> [](#__codelineno-1-2) <img src="https://marimo.io/shield.svg" /> [](#__codelineno-1-3)</a>

IntegrationDescription
MotherDuckIntegrating with MotherDuck
Google Cloud StorageIntegrating with Google Cloud Storage
Google Cloud BigQueryIntegrating with Google Cloud BigQuery
Google SheetsIntegrating with Google Sheets

Security Model

When you open a notebook, marimo assumes you might not trust its contents until you explicitly choose to run it. Once you've run code, marimo treats the outputs as trusted since they came from your execution.

Like other notebooks, marimo allows arbitrary code execution when you run cells. This means that if you run code from untrusted sources, you could inadvertently execute malicious code. Therefore, it's important to only run notebooks from sources you trust or to review the code before executing it.

However, marimo implements several security measures to minimize risks when opening and editing notebooks. Our blanket policy is that no user code is executed without explicit user action (either as javascript or python).

Content sanitization

marimo sanitizes HTML and JavaScript in specific contexts to prevent malicious code from executing when you open untrusted notebooks. All user content shown before execution is sanitized to remove all scripts (including markdown and custom HTML outputs).

After initial execution, outputs are trusted since they were generated by your code. Being a responsible notebook user means running code from sources you trust, and/or reviewing code before executing it.

Static loading

Although marimo notebook are just python files, opening a notebook through marimo edit does not execute it as a module. marimo notebooks are statically loaded, meaning they are parsed but not executed as Python modules when opened. This prevents arbitrary code execution at load time. Code only runs when you explicitly execute cells.

Run modes and trust

marimo behaves differently depending on how you run it:

Edit mode (marimo edit):

  • Content is sanitized until you run your first cell or auto_instantiate is enabled (by default it is disabled)
  • After you run code, subsequent outputs are trusted (you created them)
  • Token authentication enabled by default for remote access

Run mode (marimo run):

  • Notebooks run as web applications
  • Content is treated as a trusted website (no sanitization)
  • Token authentication can be configured via CLI flags or custom middleware
  • With marimo run <folder> --watch, newly created notebooks in the watched folder can appear in gallery mode without restarting the server

This distinction reflects the different threat models: editing is exploratory and may involve untrusted notebooks; deployed apps are intentional publications.

Authentication

marimo provides token-based authentication:

  • Enabled by default when running marimo edit
  • Configurable in run mode via --token and --token-password flags
  • Extensible through ASGI middleware for custom authentication schemes

See the Authentication guide for more details.

Added security measures on https://molab.marimo.io

molab takes a few other addition precautions.

  • Auto-running cells is disabled on notebook load (you can disable this during your session)
  • Custom head tags are disabled

These restrictions prevent code execution without explicit user consent.

Security Advisories

marimo publishes security advisories for vulnerabilities that affect production deployments, particularly long-running applications. We follow responsible disclosure practices and work with security researchers to address issues.

CVE Policy

We issue CVEs and security advisories when:

  • A vulnerability could affect long-running app deployments
  • End-users are directly impacted
  • The issue has security implications beyond normal bug fixes

For general safety improvements and hardening work, we document changes in our release notes without issuing formal advisories.

molab Security

molab is marimo's hosted notebook platform. For security issues affecting molab:

  • We handle disclosure on a case-by-case basis
  • General security improvements are disclosed publicly when applicable, and will be documented on this page.
  • User-specific issues are handled privately through direct notification
  • Reports can be submitted through the same channels: GitHub advisories or security [at] marimo [dot] io

Reporting Vulnerabilities

We appreciate the security research community's efforts to improve marimo's security. If you discover a vulnerability:

How to report:

  1. Draft a security advisory on GitHub, or
  2. Email the marimo team at security [at] marimo [dot] io

What to expect:

  • We review all reports and respond to actionable issues
  • Advisories affecting end-users are escalated to CVEs when appropriate
  • We provide attribution for all reports (unless you prefer to remain anonymous)
  • We have a small allocation for bug bounties; please inquire if interested.

Recognition:

We're grateful to the security researchers who have responsibly disclosed vulnerabilities. Your contributions help keep marimo safe for the entire community. We encourage responsible disclosure and recognize all security researchers who help improve marimo.

Staying Up to Date

marimo ships new releases approximately once per week, and we provide immediate updates for major security disclosures. To ensure you have the latest security fixes, we recommend using uv to keep marimo up to date:

[](#__codelineno-0-1)# Install or update to the latest version [](#__codelineno-0-2)uv pip install --upgrade marimo

Using uv ensures you benefit from the latest security improvements and patches as soon as they're available.

Questions?

For security questions or concerns, please reach out to security [at] marimo [dot] io. For general questions about marimo, see our FAQ or join us on Discord.

Previous Advisories

Click to expand previous security advisories

  • [GHSA-xjv7-6w92-42r7]: Unauthenticated proxy vulnerability in matplotlib endpoint. The /mpl/[port]/[route] endpoint allowed external attackers to reach internal services. Affected versions 0.9.20 through 0.16.3. Fixed in 0.16.4.
  • [GHSA-2679-6mx9-h9xc]: Remote code execution via unauthenticated terminal access in edit mode. The terminal panel did not require authentication, allowing unauthenticated users to execute arbitrary commands on instances of marimo edit exposed to the internet. Run mode (marimo run) is not affected. Affected versions 0.7.10 through 0.22.x. Fixed in 0.23.0. See our advisory for more information.
  • [molab-0]: iframe sandbox escape via markdown render. In molab, an attacker could exploit a vulnerability in the iframe sandboxing to escape the iframe and execute code in the parent context. Fixed in molab deployment on 2025-10-19.

Setting up a virtual environment

Python uses virtual environments to minimize conflicts among packages. Here's a quickstart for pip users. If you use conda, please use a conda environment instead.

Run the following in the terminal:

  • create an environment with python -m venv marimo-env
  • activate the environment:
  • macOS/Unix: source marimo-env/bin/activate
  • Windows: marimo-env\Scripts\activate

Make sure the environment is activated before installing marimo and when using marimo. Install other packages you may need, such as numpy, pandas, matplotlib, and altair, in this environment. When you're done, deactivate the environment with deactivate in the terminal.

Learn more from the official Python tutorial.

Using uv?

uv is a next-generation Python package installer and manager that is 10-100x faster than pip, and also makes it easy to install Python and manage projects. Create a uv project with uv init; this creates and manages a virtual environment for you behind-the-scenes. For detailed information on using marimo with uv, see our uv guide.

Prefer VS Code/Cursor?

Try our extension, which works in VS Code, Cursor, and other VS Code forks.

Install with minimal dependencies

To install marimo, run the following in a terminal:

install with pipinstall with uvinstall with conda

To check if the install worked, run

To check if the install worked, run

[](#__codelineno-3-1)uv run marimo tutorial intro

[](#__codelineno-4-1)conda install -c conda-forge marimo

To check if the install worked, run

A tutorial notebook should open in your browser.

Install with recommended dependencies

marimo is lightweight, with few dependencies, to maximize compatibility with your own environments.

To unlock additional features in the marimo editor, including SQL cells, AI completion, server-side plotting of dataframe columns, and more, we suggest installing marimo[recommended]:

install with pipinstall with uvinstall with conda

[](#__codelineno-6-1)pip install "marimo[recommended]"

[](#__codelineno-7-1)uv add "marimo[recommended]"

[](#__codelineno-8-1)conda install -c conda-forge marimo "duckdb>=1.0.0" "altair>=5.4.0" pyarrow "polars>=1.9.0" "sqlglot[c]>=23.4" "openai>=1.55.3" "ruff" "nbformat>=5.7.0" "vegafusion>=2.0.0" "vl-convert-python>=1.0.0"

Installing marimo in this way installs the following additional dependencies and unlocks the following features:

DependencyFeature
duckdb>=1.0.0SQL cells
altair>=5.4.0Plotting in datasource viewer
polars[pyarrow]>=1.9.0SQL output back in Python
sqlglot[c]>=23.4SQL cells parsing
openai>=1.55.3AI features
ruffFormatting
nbformat>=5.7.0Export as IPYNB
vegafusion>=2.0.0Performant charting
vl-convert-python>=1.0.0Required by vegafusion

marimo is a reinvention of the Python notebook. As a reinvention, marimo may push to you rethink what a notebook is. The following readings and videos might help you do just that.

To dive deep into what we're building and why, check out these readings:

See our blog for more.

YouTube

Our YouTube channel shows you the ins and outs of using marimo for many applications, including AI, ML, data engineering, and more. You can also get started with the marimo concepts playlist, which tours many of our features.

You may also enjoy this video, which highlights some of the more advanced features that can really help you get the most out of marimo.

  • marimo lets you rapidly experiment with data using Python, SQL, and interactive elements in a reproducible notebook environment.
  • Unlike Jupyter notebooks, marimo notebooks are reusable software artifacts. marimo notebooks can be shared as as interactive web apps and executed as Python scripts.

Editing notebooks

marimo notebooks are reactive: they automatically react to your code changes and UI interactions and keep your notebook up-to-date, not unlike a spreadsheet. This makes your notebooks reproducible, eliminating hidden state; it's also what enables marimo notebooks to double as apps and Python scripts.

Working with expensive notebooks

If you don't want cells to run automatically, the runtime can be configured to be lazy, only running cells when you ask for them to be run and marking affected cells as stale. See our guide on working with expensive notebooks for more tips.

Create your first notebook. After installing marimo, create your first notebook with

[](#__codelineno-0-1)marimo edit my_notebook.py

at the command-line.

The marimo library. We recommend starting each marimo notebook with a cell containing a single line of code,

The marimo library lets you use interactive UI elements, layout elements, dynamic markdown, and more in your marimo notebooks.

How marimo executes cells

A marimo notebook is made of small blocks of Python code called cells. When you run a cell, marimo automatically runs all cells that read any global variables defined by that cell. This is reactive execution.

Execution order. The order of cells on the page has no bearing on the order cells are executed in: execution order is determined by the variables cells define and the variables they read.

You have full freedom over how to organize your code and tell your stories: move helper functions and other "appendices" to the bottom of your notebook, or put cells with important outputs at the top.

No hidden state. marimo notebooks have no hidden state because the program state is automatically synchronized with your code changes and UI interactions. And if you delete a cell, marimo automatically deletes that cell's variables, preventing painful bugs that arise in traditional notebooks.

No magical syntax. There's no magical syntax or API required to opt-in to reactivity: cells are Python and only Python. Behind-the-scenes, marimo statically analyzes each cell's code just once, creating a directed acyclic graph based on the global names each cell defines and reads. This is how data flows in a marimo notebook.

Minimize variable mutation.

marimo's understanding of your code is based on variable definitions and references; marimo does not track mutations to objects at runtime. For this reason, if you need to mutate a variable (such as adding a new column to a dataframe), you should perform the mutation in the same cell as the one that defines it.

Learn more in our reactivity guide.

For more on reactive execution, open the dataflow tutorial

or read the reactivity guide. To visualize and understand how data flows through your notebook, check out our dataflow tools.

Visualizing outputs

marimo visualizes the last expression of each cell as its **ou

… [truncated — open the raw llms.txt above for the full file]

Related

The AI Toolkit for TypeScript, from the creators of Next.js.

/llms.txt
136,985 tokens
Developer Tools

Meet the modern standard for public facing documentation. Beautiful out of the box, easy to maintain, and optimized for user engagement.

/llms.txt
5,436 tokens
/llms-full.txt
181,290 tokens
Developer Tools

Web development for the rest of us.

/llms.txt
602 tokens
/llms-full.txt
453,623 tokens
Developer Tools

Search through billions of items for similar matches to any object, in milliseconds. It’s the next generation of search, an API call away.

/llms.txt
15,715 tokens
/llms-full.txt
588,629 tokens
Developer Tools

Build and deploy reliable background jobs with no timeouts and no infrastructure to manage.

/llms.txt
12,202 tokens
/llms-full.txt
387,586 tokens
Developer Tools

Get the simple developer experience of SQLite in production, and scale your multi-tenant backend with unlimited databases.

/llms.txt
10,006 tokens
/llms-full.txt
163,317 tokens
Developer Tools

Upstash is a serverless data platform providing low latency and high scalability for real-time applications.

/llms.txt
52,307 tokens
/llms-full.txt
1,200,134 tokens
Developer Tools

One-click deployments built for teams, tuned for Laravel, loaded with tools and goodies you're going to love.

/llms.txt
565 tokens
/llms-full.txt
11,330 tokens
Developer Tools