Skip to main content
marimo notebooks are designed from the ground up to work seamlessly with version control systems like Git. Unlike traditional JSON-based notebooks, marimo stores notebooks as pure Python files, making them naturally compatible with standard developer workflows.

Git-Friendly Architecture

marimo notebooks are stored as .py files, which provides significant advantages for version control:
  • Plain text format: Easy to read, diff, and merge
  • No JSON metadata: No hidden state or execution counts
  • Standard Python syntax: Works with all Python tools
  • Meaningful diffs: See actual code changes, not format noise

Notebook File Structure

A marimo notebook is a standard Python script:
This structure makes it easy to:
  • Review changes in pull requests
  • Track code evolution over time
  • Merge contributions from multiple authors
  • Revert problematic changes

Working with Git

Initializing a Repository

marimo notebooks work with standard Git workflows:

Viewing Changes

Use standard Git commands to view notebook changes:
Because notebooks are Python files, the diffs are meaningful and show actual code changes:

Committing Notebooks

Commit notebooks like any other Python file:
Write clear commit messages that describe the notebook’s analytical changes, not just code modifications:"Add correlation analysis and visualization""Update notebook.py"

Diffing and Merging

marimo’s Python-based format makes diffing and merging straightforward.

Understanding Notebook Diffs

When reviewing changes, focus on:
  1. Cell content: The actual code logic within @app.cell decorators
  2. Cell dependencies: Changes to function parameters (e.g., def __(pd, np))
  3. Return values: What each cell exports (e.g., return df,)
  4. Imports: New or modified dependencies

Merging Changes

merge branches using standard Git commands:

Handling Merge Conflicts

When conflicts occur, they appear as standard Python code conflicts:
Resolve conflicts by:
  1. Editing the file to choose or combine changes
  2. Removing conflict markers (<<<<<<<, =======, >>>>>>>)
  3. Testing the notebook: marimo edit notebook.py
  4. Committing the resolution: git add notebook.py && git commit
After resolving conflicts, always run the notebook to ensure cells execute correctly and dependencies are maintained.

Rebase Workflows

marimo notebooks work seamlessly with rebasing:
Because notebooks are Python files, rebase operations preserve code structure and don’t introduce spurious changes.

Collaboration Workflows

marimo’s Git compatibility enables effective team collaboration.

Pull Request Best Practices

When creating pull requests with notebook changes:
Explain the analytical or scientific changes:
Limit each PR to a single analysis or feature:✅ One PR: Add new data cleaning pipeline✅ Separate PR: Add visualization for cleaned data❌ One large PR: Refactor, add features, change visualizations
Ensure the notebook runs completely:
If you add new packages, document them:
Or use marimo’s package management to inline dependencies:
pyproject.toml

Code Review Tips

When reviewing notebook changes:
Focus on:
  1. Logic correctness: Are the data transformations valid?
  2. Cell dependencies: Do cells reference the right variables?
  3. Reactivity: Will cells update correctly when dependencies change?
  4. Performance: Are there expensive operations that could be optimized?
  5. Documentation: Are complex cells explained with comments?
Test the notebook:

Shared Configuration

Share team configurations using pyproject.toml:
pyproject.toml
Commit this file to ensure consistent notebook behavior across the team.

Git Workflow Patterns

Feature Branch Workflow

Trunk-Based Development

Release Workflow

Advanced Git Features

Git Hooks

Automate notebook quality checks with Git hooks:
.git/hooks/pre-commit
Or use marimo’s formatting:
.git/hooks/pre-commit

Git Attributes

Optimize Git operations for notebooks:
.gitattributes

Git Ignore

Exclude marimo-specific temporary files:
.gitignore
The global ~/.config/marimo/marimo.toml is user-specific and should not be committed. However, project-specific .marimo.toml or pyproject.toml configurations should be version controlled.

Comparing with Jupyter Notebooks

marimo’s version control advantages over Jupyter:

Converting from Jupyter

Convert Jupyter notebooks to marimo for better version control:

Best Practices Summary

  • Commit notebooks as .py files
  • Write descriptive commit messages about analytical changes
  • Test notebooks before committing (run all cells)
  • Use branches for experimental analyses
  • Share configuration via pyproject.toml
  • Review diffs carefully for cell dependencies
  • Document complex analytical decisions in comments
  • Use standard Git workflows (PRs, code review)
  • Don’t commit .marimo.toml user configs (unless project-specific)
  • Don’t make unrelated changes in a single commit
  • Don’t commit untested notebooks
  • Don’t ignore merge conflicts without testing
  • Don’t commit sensitive data or API keys
  • Don’t use notebooks for compiled outputs (use scripts)

Troubleshooting

Cause: Merge conflict resolution broke cell dependenciesSolution:
  1. Open in marimo editor: marimo edit notebook.py
  2. Check for syntax errors or missing variables
  3. Verify cell dependencies in the dataflow graph
  4. Run cells individually to identify the issue
Cause: Auto-formatting or dependency reorderingSolution:
  1. Configure consistent formatting in pyproject.toml:
  2. Format before committing: marimo format notebook.py
  3. Ensure all team members use same marimo version
Cause: Accidentally committed data or credentialsSolution:
  1. Use BFG Repo-Cleaner or git-filter-repo to remove sensitive data
  2. Add data files to .gitignore
  3. Use environment variables for credentials (load from .env)
  4. Review commits before pushing: git diff HEAD