1# jupyterlite-numbl-kernel
3A MATLAB-syntax kernel for [JupyterLite](https://jupyterlite.readthedocs.io/) —
4notebooks that run **entirely in the browser**, with no server, no kernel
5process, and nothing for the reader to install.
7The language engine is [numbl](https://github.com/flatironinstitute/numbl), an
8open-source MATLAB-syntax implementation in TypeScript. Each kernel runs a
9numbl session in a Web Worker in the page: variables persist across cells,
10console output streams into the running cell, MATLAB plotting commands render
11as figures in cell outputs (including interactive 3-D), and the `mip` package
12manager can install MATLAB-syntax packages from GitHub — all client-side.
14**Demo site:**
15<https://concept-collection.github.io/jupyterlite-numbl-kernel/> (deployed
16from this repo via GitHub Pages — see `.github/workflows/deploy.yml`)
18## Why
20Existing MATLAB/Octave Jupyter kernels require the real product installed
21behind a server. This kernel is a proof of concept that a MATLAB-syntax
22notebook can be a static web page: hostable on GitHub Pages, shareable as a
23link, and executable by anyone with a browser.
25## How it works
27Three small pieces, all in this repo:
29- **Kernel** (`src/kernel.ts`) — implements JupyterLite's `BaseKernel` from
30 `@jupyterlite/services`. `execute_request` forwards the cell source to a
31 numbl session (`createNumblSession` / `session.execute` from
32 `numbl/browser`, a Web Worker that numbl manages). Output streams back as
33 `stream` messages; the run's plot instructions are published as
34 `display_data` with the mime type `application/vnd.numbl.figure+json`.
35- **Figure renderer** (`src/mime.tsx`) — a JupyterLab mime renderer for that
36 mime type: it replays the instructions through numbl's figures reducer and
37 mounts numbl's React `FigureView` (from `numbl/graphics`). Outputs are
38 plain JSON, so saved notebooks re-render wherever the extension is
39 installed.
40- **Kernel registration** (`src/index.ts`) — registers the kernelspec with
41 JupyterLite's `IKernelSpecs`.
43## Build a site with it
45```bash
46pip install jupyterlite-core jupyterlite-numbl-kernel
47jupyter lite build --contents my-notebooks --output-dir dist
48# dist/ is a static site — serve it anywhere
49```
51The `demo/` directory in this repo contains the demo site sources
52(notebooks + requirements); `.github/workflows/deploy.yml` builds and
53deploys it to GitHub Pages.
55## Limitations (proof of concept)
57- **No interrupt**: a runaway cell can only be stopped by restarting the
58 kernel (restart works and gives a fresh workspace). Cooperative
59 cancellation exists in numbl but needs `SharedArrayBuffer`, i.e.
60 cross-origin isolation headers, which plain GitHub Pages doesn't set.
61- **No `input()`** (stdin), for the same reason.
62- **Figures are per-cell** (like inline matplotlib): each cell renders the
63 figures its own commands produce; `hold on` does not span cells.
64- **Named function definitions are not supported inside cells** (a numbl
65 REPL limitation) — anonymous functions work; named functions belong in
66 `.m` files.
67- **uihtml** components render display-only; the MATLAB↔HTML event bridge
68 is not wired into outputs yet.
69- Notebook files from the JupyterLite contents (e.g. sibling `.m` files)
70 are not yet synced into the numbl session's virtual filesystem.
71- numbl itself is not MATLAB: it covers a large, tested subset of the
72 language and toolbox surface. See the
73 [numbl repo](https://github.com/flatironinstitute/numbl) for scope.
75## Development
77Requires Python ≥ 3.9 and NodeJS ≥ 20, and `numbl >= 0.4.14` on npm (the
78first release with the incremental `session.execute` browser API). To
79develop against an unreleased numbl checkout, run `npm pack` there and
80point the `numbl` dependency at the tarball.
82```bash
83python -m venv .venv && source .venv/bin/activate
84pip install "jupyterlab~=4.6.0" "jupyterlite-core==0.8.1"
86jlpm install
87jlpm build # tsc + labextension (dev)
88pip install -e . # editable install, registers the labextension
90# Build and serve the demo site locally
91pip install -r demo/requirements.txt
92jupyter lite build --lite-dir demo --contents content --output-dir demo/_output
93python -m http.server -d demo/_output 8000
94```
96`jlpm watch` rebuilds on change during development.
98## License
100Apache-2.0. Built on [numbl](https://github.com/flatironinstitute/numbl) and
101the [JupyterLite](https://github.com/jupyterlite/jupyterlite) kernel API;
102scaffolding follows the
103[jupyterlite/echo-kernel](https://github.com/jupyterlite/echo-kernel)
104template.