petercorke / petercorke/robotics-toolbox-python
JupyterLite: dual-build dispatcher (JSPI-capable vs. legacy Pyodide) to unstick the pinned kernel version
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3.5k
- Forks
- 624
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 53
Description
Background
ci.yml's JupyterLite build pins jupyterlite-pyodide-kernel==0.6.1 (bundling Pyodide 0.27.6) deliberately, to stay behind Pyodide's default-on WebAssembly JSPI ("stack switching", on by default since 0.27.7) — Safari has no JSPI support as of 2026-08, Firefox only behind a flag. Without this pin, jupyterlite-pyodide-kernel's use of run_until_complete() either crashes the kernel outright in those browsers, or (with the enableRunUntilComplete: false workaround) silently races package installs. Full rationale in the toolbox-maintainer skill's JupyterLite version-pinning section. Same pin, same reason, on MVTB and bdsim.
As of the pure-Python-wheel fix (see the PR this issue was filed alongside), RTB's own wasm wheel no longer has any ABI coupling to a specific Pyodide/Emscripten version — a py3-none-any wheel works under any Pyodide version. So the pin is no longer needed for our own package's sake. It's still needed for the kernel-crash/JSPI reason above, independent of anything RTB ships.
The remaining cost of staying pinned: everything Pyodide bundles internally (numpy, scipy, etc., for anyone micropip.install-ing them in a live notebook) stays frozen at whatever versions Pyodide 0.27.6 shipped, indefinitely — until Safari/Firefox ship JSPI for real.
Proposed idea (not yet designed/committed to)
A lightweight client-side dispatcher page in front of the JupyterLite "Try it Now" link: feature-detect real JSPI support (typeof WebAssembly.Suspending === "function") and redirect to one of two parallel JupyterLite deployments — a modern build (current kernel/Pyodide, JSPI on) for browsers that support it, and today's pinned legacy build for those that don't. Feature detection (not user-agent sniffing) means Safari/Firefox users automatically graduate to the modern build the day their browser ships JSPI, with no code changes needed here.
Why not done now
This is a real but secondary problem — it predates and is independent of the pure-Python-wheel fix, which was this session's actual scope. The dispatcher approach is a genuine scope increase: two parallel JupyterLite deployments, extra CI build time, extra static hosting, a dispatcher page, and testing both paths. Per the toolbox-maintainer skill's cross-repo consistency principle, doing this "properly" means MVTB and bdsim too, not just RTB, since all three carry the identical pin for the identical reason.
Next steps, if picked up
- Confirm
WebAssembly.Suspendingis still the correct JSPI feature-detection API at the time this is implemented. - Decide whether to build this once as a shared pattern (e.g. documented in
rvc-ecosystem) rather than three independent implementations. - Weigh the hosting/CI cost against the actual benefit (how stale do Pyodide's bundled scientific packages actually get in practice, and does anyone's notebook usage actually hit that staleness).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading ci.yml and the current JupyterLite build and kernel pin. Confirm the JSPI detection API, then evaluate the two-deployment and hosting approach across RTB, MVTB, and bdsim. Done would mean an agreed implementation path with both modern and legacy browser routes tested, or a documented decision not to proceed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- jupyter, python, wasm
- Domain
- build-system, ci-cd, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100