Compiling Python to
WebAssembly
Syrus Akbary March 2024
And how we got here…
Slide 2
Slide 2 text
Who am I?
Slide 3
Slide 3 text
No content
Slide 4
Slide 4 text
No content
Slide 5
Slide 5 text
No content
Slide 6
Slide 6 text
No content
Slide 7
Slide 7 text
I want to make it
universal!
Circa 2018
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
Can I compile Graphene
to WebAssembly?
WebAssembly could help on the quest of having an universal GraphQL library!
Slide 10
Slide 10 text
such cool
WOW
very Wasm
Slide 11
Slide 11 text
❤ Python
Backend:
+ >
Running at:
Slide 12
Slide 12 text
Could we run Wasmer’s Python
backend performantly?
Slide 13
Slide 13 text
Use the CPython
interpreter in Wasm
Slide 14
Slide 14 text
But…
performance sucked
Using the CPython interpreter was not the fastest solution
Slide 15
Slide 15 text
How to improve
performance
Slide 16
Slide 16 text
Making Python go
brr brr in Wasm
• Use a Python subset that can
be compiled into performant
code
• Use JIT inside of Python
• Use Static Analysis to
optimize code
Slide 17
Slide 17 text
Python subset
• Codon
➡ github.com/exaloop/codon
• RPython
➡ rpython.readthedocs.io
• Cython
Optimize a smaller set
✅ Can be compiled to very
performant code
❌ Doesn’t support the full syntax
or modules
JS Equivalent: Assemblyscript
Slide 18
Slide 18 text
RPython
Transforms the typed code into C, and then compiles it
$ rpython hello_world.py
hello-world-c.c
Slide 19
Slide 19 text
But…
dictionaries couldn’t be dynamic
Using unmodi
f
ied code was challenging
Slide 20
Slide 20 text
Codon
Transforms a subset of Python code into LLVM IR
Slide 21
Slide 21 text
But…
many incompatibilities with Python
Using unmodi
f
ied code was challenging
Slide 22
Slide 22 text
Python JITs
• Pypy
➡ pypy.org
Compile the hot paths
✅ Really fast speeds
❌ Needs to warm up
❌ Not trivial to support with
Wasm (but possible) JS Equivalent: V8, JasvascriptCore, SpiderMonkey
Slide 23
Slide 23 text
PyPy JIT
*Don’t miss Dmitry’s talk on JITs on Wasm with Spidermonkey
🔗 pypyjs.org
Slide 24
Slide 24 text
But…
it would take a bit more time to get
right!
JITs are possible, but not trivial -> More development time!
Slide 25
Slide 25 text
Static Analysis
• Mypy & Mypy-c
➡ mypy-lang.org
• Nuitka
➡ github.com/Nuitka/Nuitka
Performant code based on the types
✅ Mostly compatible with Python
❌ Only 1.5-3x faster
❌ Complex to get right
❌ Larger binaries JS Equivalent: Static Hermes, TypescriptCompiler
Slide 26
Slide 26 text
MyPy-C
🔗 mypyc.readthedocs.io
Slide 27
Slide 27 text
Nuitka
Python to CPython transpiler
• It supports most Python programs. Transpiles Python code into the
corresponding CPython calls
• It can even work as a code obfuscator (no one will be able to decompile
your program!)
Slide 28
Slide 28 text
But… but…
no buts, let’s try it!
Everything promising, so far…
Slide 29
Slide 29 text
Demo time!
Using Nuitka natively
Slide 30
Slide 30 text
Will it compile to WASI?
If Nuitka generates C code, and then uses a compiler…
can we just switch the compiler?
Slide 31
Slide 31 text
Not that
simple!
❌ Not compatible with
Python 3.12+
❌ Doesn’t support
cross compiling to
di
ff
erent architectures
(64 to 32 bits)
Slide 32
Slide 32 text
🥁
(prepare for big announcement)
Slide 33
Slide 33 text
Announcing py2wasm 🎉
A Python to WebAssembly compiler (using Nuitka)
Slide 34
Slide 34 text
1. Install py2wasm 2. Run
Slide 35
Slide 35 text
It’s fast… Very fast
3x
faster
Slide 36
Slide 36 text
Plan Ahead
• Compile Wasmer Django
backend to Wasm via py2wasm
• Use WASIX for full asyncio,
threads and sockets support
• py2wasm working fully inside
of wasmer
Future plans!
Slide 37
Slide 37 text
Stay tuned in wasmer.io :)
Upcoming post coming (very) soon!