CPython's main branch running in the browser with WebAssembly

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • Appwrite - The Open Source Firebase alternative introduces iOS support
  • Scout APM - Less time debugging, more time building
  • SonarLint - Deliver Cleaner and Safer Code - Right in Your IDE of Choice!
  • pyodide

    Pyodide is a Python distribution for the browser and Node.js based on WebAssembly

    Yes, currently input goes into a propmpt() and it doesn't output anything unless you hit "Cancel" on the prompt, definitely a bad time.

    Python allows you to reach in and replace the core interpreter loop, so this may be an avenue to have our own asyncify-like function pop out to JS land and restore state correctly (which we can be smart about since we are the interpreter).

    It may also be possible to write something that runs Python in a webworker and communicate with it over a sharedarraybuffer, but that I'm a bit more hazy on. Pyodide has some discussion of this in https://github.com/pyodide/pyodide/issues/1219 and https://github.com/pyodide/pyodide/issues/1503.

    This is definitely the hardest part of getting Python to work. Well, hardest after the hardest part of building a compiler toolchain like Emscripten :)

  • wasm-libxml2

    A quick experiment to build and run libxml2 as a WebAssembly module.

    Very cool, I did some experiments with libxml on a WASI environment a few years ago (https://github.com/matiasinsaurralde/wasm-libxml2).

  • Appwrite

    Appwrite - The Open Source Firebase alternative introduces iOS support . Appwrite is an open source backend server that helps you build native iOS applications much faster with realtime APIs for authentication, databases, files storage, cloud functions and much more!

  • lunatic

    Lunatic is an Erlang-inspired runtime for WebAssembly

    It's on the embedder (Wasm VM) to provide this functionality. I'm working on a Wasm runtime [0] that is written in Rust and uses stack switching to allow you to call Rust async functions as if they were blocking. This keeps the Wasm bytecode simple (blocking), but at the same time provides high performance i/o.

    There is also a proposal to bring stack switching to the browser.

    [0]: https://github.com/lunatic-solutions/lunatic

  • emscripten

    Emscripten: An LLVM-to-WebAssembly Compiler

    Trying to figure this out myself... did some code and blog reading. sys.stdin almost certainly points to /dev/stdin within python. And in the browser, the filesystem is mocked out so reading from /dev/stdin just calls a direct function.

    In the browser, this calls window.prompt() which is sort of blocking. NodeJS calls nodeFS.readSync. So the 'wait for event' is just pushed to a lower layer. https://github.com/emscripten-core/emscripten/blob/4a9d5ab94...

    The syscalls themselves don't look async. https://github.com/emscripten-core/emscripten/blob/9ac6f11a2... https://github.com/emscripten-core/emscripten/blob/a9923b596...

  • absurd-sql

    sqlite3 in ur indexeddb (hopefully a better backend soon)

    I know Absurd SQL[0] uses SharedArrayBuffer and Atomics to turn the async IndexDB into sync for use by Wasm. I wander if it’s possible to use that here too although it’s obviously a little different?

    0: https://github.com/jlongster/absurd-sql

    1: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

    2: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

  • webassembly.sh

    Open-source and installable PWA terminal powered by WebAssembly, WAPM, and Wasmer-JS 🖥

    In WebAssembly.sh (https://github.com/wasmerio/webassembly.sh) they run WASM binaries in a Web Worker and then use `SharedArrayBuffer` to block the WebWorker while the main thread does some work (e.g. collect input). You could use a similar solution.

    When building Runno (https://runno.dev) I forked off that project and did a bunch of other things on top to get blocking to work in Safari and non-cross-origin-isolated contexts.

    Ultimately I think it's JavaScript's (or whichever host language) responsibility to block when the binary calls out (if that is the expected semantics).

  • fengari

    🌙 φεγγάρι - The Lua VM written in JS ES6 for Node and the browser

    > I’d expect MicroPython (or Lua/mruby/etc) could be an order of magnitude smaller. Still larger (and slower) than just using JavaScript, though.

    Fengari [0], a Lua interpreter written in JS, is a little over 200Kb. (And was intentionally written in JS [1] because of a variety of reasons that made WASM not work that well.

    200Kb isn't that bad of a price to pay to switch languages, on most websites. It'll be about the cost of a single image added to the page. And it's fairly performant.

    For most sites, the costs in terms of requests and performance will be negligible compared to what you're trying to achieve.

    And Fengari makes it nice and easy to interact with JS, too. Using React with Lua's syntax was what sold me on it. No ecosystem lockout, like I'd expect with most WASM ports.

    [0] https://fengari.io/

    [1] https://hackernoon.com/why-we-rewrote-lua-in-js-a66529a8278d

  • Scout APM

    Less time debugging, more time building. Scout APM allows you to find and fix performance issues with no hassle. Now with error monitoring and external services monitoring, Scout is a developer's best friend when it comes to application development.

  • pypyjs

    PyPy compiled to JavaScript

    I don't remember that game specifically, but I assume it used PyPy.js,


NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts