How it’s built · Polyglot notebooks

Notebook Lab

A notebook where each cell can be a different language and they all share one set of variables. A Python cell computes, a JavaScript cell turns the result into a chart, a slider in a controls cell changes the input, and an HTML cell redraws as you drag it. A model can write any cell, build a whole notebook from one request, or repair a cell that failed. Nothing runs on a server: every language runs in your browser.

Open Notebook Lab Open the boids example
Notebook Lab running the boids example: four sliders in a controls cell steer a flock drawn live in an HTML cell, with the shared variables listed beside it.
The boids example. The sliders write four notebook variables; the flock below reads them every frame, so it changes while you drag.

One notebook, one set of variables

  1. PythonRuns in Pyodide (CPython compiled to WebAssembly), with NumPy, pandas and matplotlib. Writes nb["key"] = value.
  2. JavaScriptReads nb.get("key"), and returning a Vega-Lite spec renders an interactive chart.
  3. C and LuaFull programs that publish results by printing a tagged line: __NB_SET__ {"key":…}.
  4. ControlsSliders, pickers and buttons declared as JSON and bound to variables. A visual designer edits the layout.
  5. HTMLSandboxed frames that receive every change over a message bridge, so a canvas can redraw while a slider moves.

Design decisions

The runtime is not the UI

Executing a cell or a whole notebook is a plain service that returns results. The editor uses it, so does a small window.NotebookLabAPI, and so does a headless sweep that runs every bundled example in Chrome and reports any cell that fails.

Untrusted frames, trusted bridge

HTML cells run in sandboxed frames with an opaque origin, so they cannot reach the page or its storage. They get a small nb object instead, seeded with a snapshot and kept current with single-key patches; the parent accepts writes only from the frame it created.

Generated notebooks are a contract

A whole notebook comes back as strict JSON and is checked before you see it: known cell kinds, valid chart and control JSON, the languages you allowed, the visual output you asked for. It arrives as a draft, and nothing in your notebook changes until you accept it.

Packages that can be trusted

Python packages load the first time a cell imports them. Each file is checked against the SHA-256 in Pyodide’s lockfile before it is installed, and this site serves its own copies, so running a notebook makes no request to anyone else.

Where the model helps

Generate writes one cell from a description, with the notebook so far as context. Generate notebook plans and writes a complete teaching sequence. Fix lights up on a cell that failed: the model gets the source, the error and the recent output and returns a corrected cell. Explain turns a cell into a plain-language Markdown note. Every AI-written cell remembers its prompt and a hash of what was generated, so the editor can show when you have changed it since.

Try these

Problems worth solving

The full version

The private workbench version adds Java, Go, Scala and Clojure, compiled with their real toolchains inside a Debian Linux system emulated in the browser, plus Rust. That system image is close to a gigabyte, too large for a static website, so this edition leaves those languages out and shows only the notebooks that run here.

More write-ups

Game Forge VR Forge Understory Studio Code Morph Lab