Deploy marimo notebooks that run entirely in the browser using WebAssembly (WASM). No Python backend required—notebooks execute directly in the user’s browser via Pyodide, a port of CPython to WebAssembly.
No backend servers to maintain, configure, or pay for. Host static files anywhere.
Instant Access
Users don’t need Python installed. Works on any device with a modern browser.
Low Latency
No network requests to remote servers. All computation happens locally.
Easy Sharing
Share via link, embed in documentation, or publish to GitHub Pages.
WASM notebooks are ideal for: interactive documentation, educational materials, blog posts, lightweight data exploration, quick prototyping, and shareable tools. For heavy computation or large datasets, use a traditional backend.
Package compatibility: Only pure Python packages or packages with pre-built WebAssembly wheels work in WASM. Packages with native C extensions not compiled for Pyodide won’t work.
marimo automatically attempts to install missing packages:
import marimo as mo# marimo will try to auto-install if not presentimport altair as altimport vega_datasetsdata = vega_datasets.data.cars()mo.ui.altair_chart(alt.Chart(data).mark_point())
Performance tip: Put import marimo as mo in its own cell with no other code. This ensures marimo loads quickly and the UI renders immediately.
❌ Heavy computation: Limited by browser performance
❌ Large datasets: Browser memory constraints (~2GB typically)
❌ Native extensions: C/C++ packages without WASM builds
❌ System calls: No real filesystem, subprocess, etc.
❌ Long-running jobs: Browser tabs can timeout
❌ Networking: Subject to CORS restrictions
For these use cases, deploy with a traditional Python backend using marimo run or programmatic deployment.
import marimo as moimport pandas as pd# Load from URL (subject to CORS)url = "https://raw.githubusercontent.com/user/repo/main/data.csv"df = pd.read_csv(url)mo.ui.table(df)
CORS restrictions: External data sources must have CORS headers that allow browser access. Many APIs don’t support this. Consider hosting data on CORS-enabled services or using a proxy.
import marimo as moimport numpy as npimport matplotlib.pyplot as pltmo.md("""# Fourier Transform DemoAdjust the parameters to see how they affect the signal:""")frequency = mo.ui.slider(1, 10, value=5, label="Frequency")frequency
import marimo as momo.md("""# Linear RegressionDrag the slider to change the slope:""")slope = mo.ui.slider(-5, 5, step=0.1, value=1, label="Slope")slope