We welcome all kinds of contributions. You don't need to be an expert in frontend or Python development to help out.
Contributions are made through pull requests. Before sending a pull request, make sure to do the following:
- Lint, typecheck, and format your code
- Write tests
- Run tests and check that they pass
- Read the CLA
Please reach out to the marimo team before starting work on a large contribution. Get in touch at GitHub issues or on Discord.
Note: We recommend that Windows developers use WSL and clone the marimo repository into the WSL environment and not the Windows mount.
Install pixi to manage your development environment. The following command uses pixi to launch a development shell with all dependencies installed, using hatch as the environment manager.
Note
As an alternative to installing pixi, you can try developing in Gitpod.
Note that developing in Gitpod is not officially supported by the marimo team.
Tip
New to both pixi and hatch? Pick pixi. It installs and manages both the Python and Node toolchains, then drops you into a ready shell with one command. Choose hatch only if you already maintain Node 20+/pnpm 9+ yourself and just want a Python environment manager. Typical flows:
pixi shell→make fe && make py→make devhatch shell→make fe && make py→make dev
pixi shellIf you have the right non-python dependencies installed via other methods (e.g. homebrew) you can simply activate your marimo development
environment with hatch shell.
Now you can install the environment frontend and Python dependencies.
make fe && make pyAfter doing this, you can instantiate your marimo development environment by running the following command.
make devThis will launch two processes, the backend one in port 2718 and the front end one in port 3000.
In summary you will need to run:
pixi shell
make fe && make py
make devor if not using pixi:
hatch shell
make fe && make py
make devYou can optionally install pre-commit hooks to automatically run the validation checks when making a commit:
uvx pre-commit installor
pixi run pre-commit installTo build the frontend unminified, run:
NODE_ENV=development make fe -BNote
Refer to the Makefile for the implementation details
| Command | Category | Description |
|---|---|---|
help |
General | 📖 Show available commands |
install-all |
Setup | 🚀 First-time setup: Install all dependencies (frontend & Python) |
check-prereqs |
Setup | ✓ Check if all required tools are installed |
py |
Setup | 🐍 Install Python dependencies in editable mode |
fe |
Build | 🔧 Build frontend assets |
test |
Test | 🧪 Run all tests (frontend, Python, end-to-end) |
check |
Test | 🧹 Run all checks |
fe-check |
Lint/Test | 🧹 Check frontend (lint, typecheck) |
fe-test |
Test | 🧪 Test frontend |
e2e |
Test | 🧪 Test end-to-end |
fe-lint |
Lint | 🧹 Lint frontend |
fe-typecheck |
Lint | 🔍 Typecheck frontend |
fe-codegen |
Build | 🔄 Generate frontend API |
py-check |
Lint | 🔍 Typecheck, lint, format python |
typos |
Lint | 🔍 Check for typos |
py-test |
Test | 🧪 Test python |
py-snapshots |
Test | 📸 Update snapshots |
wheel |
Build | 📦 Build wheel |
docs |
Docs | 📚 Build docs |
docs-serve |
Docs | 📚 Serve docs |
storybook |
Docs | 🧩 Start Storybook for UI development |
All checks.
make checkFrontend.
make fe-checkPython.
Using make |
Using hatch |
|---|---|
|
|
We have frontend unit tests, Python unit tests, and end-to-end tests. Code changes should be accompanied by unit tests. Some changes should also be accompanied by end-to-end tests.
To run all tests:
make testThis can take some time. To run just frontend tests, just Python tests, or just end-to-end tests, read below.
In the root directory, run:
make fe-testWe use pytest syntax for Python tests.
make py-testRun a specific test
hatch run +py=3.13 test:test tests/_ast/Run all changed tests
hatch run +py=3.13 test:test --pickedRun tests with optional dependencies
hatch run +py=3.13 test-optional:test tests/_ast/Run tests across all Python versions (omit +py)
hatch run test:test tests/_ast/Run all tests across all Python versions
Not recommended since it takes a long time.
hatch run test:testWe use playwright to write and run end-to-end tests, which exercise both the marimo library and the frontend.
(The first time you run, you may be prompted by playwright to install some dependencies; follow those instructions.)
For best practices on writing end-to-end tests, check out the Best Practices doc.
For frontend tests, you want to build the frontend first with make fe so that Playwright works on your latest changes.
Run end-to-end tests.
In the root directory, run:
make e2eRun tests interactively.
In frontend/:
pnpm playwright test --uiRun a specific test.
In frontend/:
| Without debugger | With debugger |
|---|---|
|
|
To open Storybook, run the following:
cd frontend && pnpm storybookYou can develop on marimo with hot reloading on the frontend and/or development mode on the server (which automatically restarts the server on code changes). These modes are especially helpful when you're making many small changes and want to see changes end-to-end very quickly.
For the frontend, you can choose to run slower hot reloading for an environment closer to production.
| Production | Development |
|---|---|
|
|
For the backend, we recommend running without auth (--no-token):
| Production | Debug |
|---|---|
|
|
- When to run with hot-reloading?: When you are developing on the frontend and want to see changes immediately. This is useful for styling, layout, new plugins, etc. Developing through the Vite server may have inconsistent behavior due to proxied api/websocket request and since the marimo Python server is not serving the HTML.
- When to develop with the frontend in watch mode?: When you are making few frontend changes, or when you want to test the frontend in a way that is closer to production.
- When to run marimo CLI with development mode?: When you are making changes to the backend and want to see debug logs. When developing on marimo plugins, you can run with "On module change" as "autorun" to see changes immediately.
Caveats for running pnpm dev
Running pnpm dev will serve the frontend from a Vite dev server, not from the
marimo server. This means that:
- You will want to run your marimo server with
--headlessand--no-tokenso it does not open a new browser tab, as it will interfere with the frontend dev server. - The tradeoff of using the frontend dev server is that it is faster to develop on the frontend, but you will not be able to test the frontend in the same way that it will be used in production.
If you use vscode, you might find the following settings.json useful:
{
"editor.formatOnSave": true,
"editor.formatOnPaste": false,
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"[typescriptreact]": {
"editor.defaultFormatter": "biomejs.biome"
}
}When submitting a pull request, marimo will run: lint, typecheck, and test jobs.
We have some labels which can influence which tests are run:
test-all: Run all tests across unchanged files as well.
Marimo has a variety of CI jobs that run on pull requests. All new PRs will fail until you have signed the CLA. Don't fret. You can sign the CLA by leaving a comment in the PR with text of I have read the CLA Document and I hereby sign the CLA