Mercury v3 – Convert Python Notebooks to Web Apps
Reactive notebook cells that fire on widget interaction beat static Streamlit callbacks.
Minimal filesystem-backed Python notebooks. Each cell is a .py file.
Filesystem-backed notebooks beat jupytext by making .py files the source of truth.
Data scientists and ML engineers who want git-friendly notebooks
jupytext · Papermill · Jupyter
Jupyter is great but the .ipynb format has always bothered me. It's JSON with embedded code — git diffs are a mess, linters don't see it, and you can't just open a cell in your editor and have things work. There are tools that help (jupytext, nbstripout) but they all work around the format rather than replacing it.
Looseleaf takes a different approach: a notebook is just a directory of .py files. Each file is a cell. They run in alphabetical order, so you use numbered prefixes (01_load.py, 02_train.py). One long-running Python process holds the shared namespace across all of them, so variables from cell 1 are available in cell 2 — same model as Jupyter, different storage.
When a cell runs, output is written to a .output sidecar file (JSON with stdout, stderr, images, timing). The browser frontend shows it, but so can anything else that can read a file.
A few things I find useful about this: edit cells in any editor — they're just .py files, a watchdog observer picks up external changes and the browser updates automatically. Git just works: git diff 02_train.py shows what you'd expect, no output noise. AI agents can work with it naturally — write a single cell without touching anything else, read the last output from the sidecar without running anything, drop in new cells by creating a file. And there are no dependencies on Jupyter: it's ~750 lines of Python (aiohttp + watchdog) and a single HTML file with Monaco loaded from CDN.
The frontend is intentionally minimal — two-mode editing like Jupyter (command/edit), Monaco for the editor, streaming output over WebSocket. No build step, no framework.
It's an opinionated tool. No markdown cells, no cell reordering in the UI, matplotlib only for plot capture. One kernel, one directory. That constraint is the point — it stays simple enough that you can read the whole thing in an afternoon.
Reactive notebook cells that fire on widget interaction beat static Streamlit callbacks.
Reactive cell execution is neat, but Streamlit and Gradio already own this space.
Haskell notebook treating reactivity as first-class. Solves real GHCi/IHaskell pain points elegantly.
Reactive notebook as agent working memory—cells persist state between actions.
Local AI analyst generates Python notebooks instead of just chat responses, keeping data on your machine.
FUSE filesystem trick makes grep usable on notebooks without modifying source files.