["python","emscripten","webassembly"]
Compiling Python to WebAssembly

I have read that it is possible to convert Python 2.7 code to Web Assembly, but I cannot find a definitive guide on how to to so. So far I have compiled a C program to Web Assembly using Emscripten and all its necessary components, so I know it is working (guide used: http://webassembly.org/getting-started/developers-guide/) What are the steps I must take in order to do this on an Ubuntu machine? Do I have to convert the python code to LLVM bitcode then compile it using Emscripten? If so, how would I achieve this?
WebAssembly vs asm.js First, let's take a look how, in principle, WebAssembly is different from asm.js, and whether there's potential to reuse existing knowledge and tooling. The following gives pretty good overview: Why create a new standard when there is already asm.js? What is the difference between asm.js and web assembly? Why WebAssembly is Faster Than asm.js Let's recapitulate, WebAssembly (MVP, as there's more on its roadmap, roughly): is a binary format of AST with static typing, which can be executed by existing JavaScript engines (and thus JIT-able or compiled AOT), it's 10-20% more compact (gzipped comparison) and an order of magnitude faster to parse than JavaScript, it can express more low-level operation that won't fit into JavaScript syntax, read asm.js (e.g. 64-bit integers, special CPU instructions, SIMD, etc) is convertible (to some extent) to/from asm.js. Thus, currently WebAssembly is an iteration on asm.js and targets only C/C++ (and similar languages). Python on the Web It doesn't look like GC is the only thing that stops Python code from targeting WebAssembly/asm.js. Both represent low-level statically typed code, in which Python code can't (realistically) be represented. As current toolchain of WebAssembly/asm.js is based on LLVM, a language that can be easily compiled to LLVM IR can be converted to WebAssembly/asm.js. But alas, Python is too dynamic to fit into it as well, as proven by Unladen Swallow and several attempts of PyPy. This asm.js presentation has slides about the state of dynamic languages. What it means is that currently it's only possible to compile whole VM (language implementation in C/C++) to WebAssembly/asm.js and interpret (with JIT where possible) original sources. For Python there're several existing projects: PyPy: PyPy.js (author's talk at PyCon). Here's release repo. Main JS file, pypyjs.vm.js, is 13 MB (2MB after gzip -6) + Python stdlib + other stuff. CPython: pyodide, EmPython, CPython-Emscripten, EmCPython, etc. empython.js is 5.8 MB (2.1 MB after gzip -6), no stdlib. Micropython: this fork. There was no built JS file there, so I was able to build it with trzeci/emscripten/, a ready-made Emscripten toolchain. Something like: git clone https://github.com/matthewelse/micropython.git cd micropython docker run --rm -it -v $(pwd):/src trzeci/emscripten bash apt-get update && apt-get install -y python3 cd emscripten make -j # to run REPL: npm install && nodejs server.js It produces micropython.js of 1.1 MB (225 KB after gzip -d). The latter is already something to consider, if you need only very compliant implementation without stdlib. To produce WebAssembly build you can change line 13 of the Makefile to CC = emcc -s RESERVED_FUNCTION_POINTERS=20 -s WASM=1 Then make -j produces: 113 KB micropython.js 240 KB micropython.wasm You can look at HTML output of emcc hello.c -s WASM=1 -o hello.html, to see how to use these files. This way you can also potentially build PyPy and CPython in WebAssembly to interpret your Python application in a compliant browser. Another potentially interesting thing here is Nuitka, a Python to C++ compiler. Potentially it can be possible to build your Python app to C++ and then compile it along with CPython with Emscripten. But practically I've no idea how to do it. Solutions For the time being, if you're building a conventional web site or web app where download several-megabyte JS file is barely an option, take a look at Python-to-JavaScript transpilers (e.g. Transcrypt) or JavaScript Python implementations (e.g. Brython). Or try your luck with others from list of languages that compile to JavaScript. Otherwise, if download size is not an issue, and you're ready to tackle a lot of rough edges, choose between the three above. Q3 2020 update JavaScript port was integrated into MicroPython. It lives in ports/javascript. The port is available as a npm package called MicroPython.js. You can try it out in RunKit. There's an actively developed Python implementation in Rust, called RustPython. Because Rust officially supports WebAssembly as compile target, no surprise there's demo link right in the top of the readme. Though, it's early. Their disclaimer follows. RustPython is in a development phase and should not be used in production or a fault intolerant setting. Our current build supports only a subset of Python syntax. Q1 2023 update Python 3.11 recognises two WebAssembly "platforms" in its documentation and documents its API availability on them among other platforms like Linux and Unix (see this PR for more details) and also recommends Pyodide (from Mozilla) and another port, PyScript (from Anaconda), based on it: The WebAssembly platforms wasm32-emscripten (Emscripten) and wasm32-wasi (WASI) provide a subset of POSIX APIs. WebAssembly runtimes and browsers are sandboxed and have limited access to the host and external resources. Any Python standard library module that uses processes, threading, networking, signals, or other forms of inter-process communication (IPC), is either not available or may not work as on other Unix-like systems. [...] For Python in the browser, users should consider Pyodide or PyScript. PyScript is built on top of Pyodide, which itself is built on top of CPython and Emscripten. Pyodide provides access to browsers’ JavaScript and DOM APIs as well as limited networking capabilities with JavaScript’s XMLHttpRequest and Fetch APIs.