Motivation
- mupt-examples currently stores 14 Jupyter notebooks (~6 MB total), where 97%+ of file size is embedded output (PNG images, HTML tables, widget state JSON)
- Git diffs on
.ipynb files are effectively unreadable -- JSON with base64-encoded images
- Current testing relies on
nbval-lax (a third-party pytest plugin) via manual shell scripts; no CI/CD exists
nbval-lax only validates "did it crash?" -- it cannot assert correctness of outputs
- Jupyter's execution model allows hidden state: cells can be run out of order, deleted variables persist, leading to notebooks that fail to reproduce
Proposal
Evaluate marimo as a replacement for Jupyter notebooks in mupt-examples. Marimo notebooks are stored as pure .py files, eliminating output bloat and enabling meaningful git diffs.
This is an exploratory proposal -- not a commitment to switch. I will investigate feasibility over the coming weeks by converting a pilot notebook and validating compatibility with our scientific Python stack.
Marimo vs Jupyter: Comparison
Advantages of Marimo
| Feature |
Jupyter |
Marimo |
| File format |
JSON with embedded outputs (~6 MB) |
Pure Python .py files (~22 KB for equivalent content) |
| Git diffs |
Unreadable (base64 images, cell metadata noise) |
Standard Python diffs |
| Testing |
Requires nbval plugin; only tests "does it run?" |
Native pytest support; embed real assertions as test_* cells |
| Reproducibility |
Cells can run out of order; hidden state accumulates |
Reactive DAG execution; no hidden state possible |
| Expensive cells |
No built-in gating; accidental re-execution of GPU cells |
mo.stop() + mo.ui.run_button() to gate expensive cells behind user interaction |
| Script execution |
Requires nbconvert or papermill |
python notebook.py works directly |
| App mode |
Requires Voila or similar |
marimo run notebook.py serves as read-only web app |
| Conversion |
N/A |
marimo convert notebook.ipynb -o notebook.py for automated migration |
Risks and Concerns
| Concern |
Assessment |
| RDKit 2D molecule rendering |
Marimo supports _repr_html_/_repr_png_ protocols. RDKit Mol objects should render via last-expression or mo.as_html(). Needs validation. |
| matplotlib 3D plots |
Natively supported. mo.mpl.interactive() adds pan/zoom. Low risk. |
rich.progress.track progress bars |
Would fall back to text output. Can optionally replace with mo.status.progress_bar. Low risk. |
IPython.display.display() calls |
Not available in marimo. Mechanical replacement with last-expression or mo.as_html(). Low risk. |
| Variable redefinition across cells |
Marimo requires each global variable to be defined in exactly one cell (DAG constraint). Some notebooks may need variable renaming or cell merging. One-time migration cost. |
| No ipywidgets support |
Marimo uses its own widget system. No current notebooks use ipywidgets directly, but this blocks future nglview/py3Dmol integration. Medium concern for future 3D molecular visualization. |
| Team familiarity |
Marimo is newer and less widely known than Jupyter. Learning curve for contributors. |
| Ecosystem maturity |
Marimo is actively developed but younger than Jupyter. Some edge cases may not be covered. |
Compatibility with Current Notebook Portfolio
| Category |
Notebooks |
Key Dependencies |
Expected Compatibility |
examples_repr/ |
5 notebooks |
mupt, rdkit, matplotlib, numpy, scipy |
High -- standard scientific Python |
examples_system/ |
4 notebooks |
mupt, rdkit, matplotlib, openff, openmm, MDAnalysis |
High -- but OpenMM GPU cells need mo.stop() gating |
examples_DPD/ |
4 notebooks |
hoomd, mbuild, flowermd, gsd, numpy |
High -- mostly text/file output, no rich display |
examples_MDAnalysis/ |
1 notebook |
(empty placeholder) |
N/A |
Testing Improvements
The strongest argument for marimo is the testing story:
- Current:
py.test --nbval-lax --current-env notebook.ipynb -- tests only that cells execute without error
- With marimo:
pytest notebook.py -- can embed real assertions like def test_atom_count(universe): assert len(universe.atoms) == 3618
- CI integration: Trivially add
pytest examples_repr/*.py examples_system/*.py to GitHub Actions (no CI exists today)
Proposed Investigation Plan
- Pilot conversion: Convert
mol_from_scratch_basic.ipynb (smallest, simplest notebook) using marimo convert
- Validate rendering: Confirm RDKit molecule depictions and matplotlib plots render correctly
- Validate testing: Add
test_* cells with real assertions, run with pytest
- Assess variable refactoring: Quantify how much manual cleanup is needed for the DAG constraint
- Decision point: Based on pilot results, decide whether to proceed with full migration
- If proceeding: Batch convert remaining notebooks, starting with
examples_repr/ (lowest risk), then examples_system/
- Add CI: GitHub Actions workflow for automated notebook testing on PR
Backward Compatibility
Marimo can export back to .ipynb format (marimo export ipynb notebook.py), so users who prefer Jupyter can still obtain notebook files. This could be automated in CI if needed.
References
Motivation
.ipynbfiles are effectively unreadable -- JSON with base64-encoded imagesnbval-lax(a third-party pytest plugin) via manual shell scripts; no CI/CD existsnbval-laxonly validates "did it crash?" -- it cannot assert correctness of outputsProposal
Evaluate marimo as a replacement for Jupyter notebooks in mupt-examples. Marimo notebooks are stored as pure
.pyfiles, eliminating output bloat and enabling meaningful git diffs.This is an exploratory proposal -- not a commitment to switch. I will investigate feasibility over the coming weeks by converting a pilot notebook and validating compatibility with our scientific Python stack.
Marimo vs Jupyter: Comparison
Advantages of Marimo
.pyfiles (~22 KB for equivalent content)nbvalplugin; only tests "does it run?"pytestsupport; embed real assertions astest_*cellsmo.stop()+mo.ui.run_button()to gate expensive cells behind user interactionnbconvertorpapermillpython notebook.pyworks directlymarimo run notebook.pyserves as read-only web appmarimo convert notebook.ipynb -o notebook.pyfor automated migrationRisks and Concerns
_repr_html_/_repr_png_protocols. RDKit Mol objects should render via last-expression ormo.as_html(). Needs validation.mo.mpl.interactive()adds pan/zoom. Low risk.rich.progress.trackprogress barsmo.status.progress_bar. Low risk.IPython.display.display()callsmo.as_html(). Low risk.Compatibility with Current Notebook Portfolio
examples_repr/examples_system/mo.stop()gatingexamples_DPD/examples_MDAnalysis/Testing Improvements
The strongest argument for marimo is the testing story:
py.test --nbval-lax --current-env notebook.ipynb-- tests only that cells execute without errorpytest notebook.py-- can embed real assertions likedef test_atom_count(universe): assert len(universe.atoms) == 3618pytest examples_repr/*.py examples_system/*.pyto GitHub Actions (no CI exists today)Proposed Investigation Plan
mol_from_scratch_basic.ipynb(smallest, simplest notebook) usingmarimo converttest_*cells with real assertions, run withpytestexamples_repr/(lowest risk), thenexamples_system/Backward Compatibility
Marimo can export back to
.ipynbformat (marimo export ipynb notebook.py), so users who prefer Jupyter can still obtain notebook files. This could be automated in CI if needed.References