This is a compelling idea. The core insight — providing a familiar exec/spawn API backed by WASM-hosted Python rather than emulating a full OS — keeps the scope tractable while still being genuinely useful.
Pyodide is the obvious foundation here. It's CPython 3.12 compiled to WebAssembly via Emscripten, and it gives you:
- A real Python interpreter in the browser
- An in-memory virtual filesystem (Emscripten FS)
micropipfor installing pure-Python packages at runtime- The ability to capture
sys.stdout/sys.stderrprogrammatically
For the architecture, I'd think of three layers:
-
Runtime layer — Pyodide loaded in a Web Worker (keeps the UI responsive). Manages the virtual filesystem and Python interpreter lifecycle.
-
Process abstraction — A JS/TS API like
exec("tool-name", ["--flag", "arg"])that returns{ stdout, stderr, exitCode }. Under the hood it would: fetch the Python script (from GitHub or a bundled location), write it to the virtual FS, redirectsys.stdout/sys.stderrto capture buffers, and run it viapyodide.runPythonAsync. -
Orchestrator — The web app that composes these "commands" into workflows, pipes output between them, etc.
On the dependency question: Pyodide's micropip can install any pure-Python wheel from PyPI (or a custom URL). For the GitHub-fetching angle, you could fetch raw .py files or even tarballs directly and unpack them onto the virtual FS — that sidesteps PyPI entirely, similar to how uv run --from git+https://... works. You wouldn't run uv itself in WASM, but you could replicate that specific fetch-and-run pattern fairly simply.
The main limitations to be upfront about:
- No real
subprocess— if a Python tool shells out to another process, that won't work natively. Your framework would need to intercept/shim that. - C-extension packages only work if Pyodide has pre-built them (numpy, etc. are available, but not everything).
- No network access from Python itself (no
requests.get()to external APIs) unless proxied through the browser's fetch.
For a demo, none of these are blockers — you just pick tools that are pure Python and don't shell out.
Want to start sketching out the API design and project structure, or would you prefer to dig deeper into any of these areas first?