Roblox’s Luau — the typed, performant Lua variant powering millions of Roblox experiences — just got a first-class WebAssembly build published to PyPI. The package luau-wasm 0.1a0 (276 KB wheel, platform tag pyemscripten_2026_0_wasm32) installs directly in Pyodide and runs in any browser. Try it: live demo.
Why This Matters
Pyodide 314.0 (released June 2026) implements PEP 783 — the pyemscripten platform specification that lets package maintainers publish WASM wheels to PyPI just like native Linux/macOS/Windows wheels. Previously, the Pyodide team manually built and hosted 300+ packages. Now the ecosystem opens to anyone with cibuildwheel and a GitHub Actions workflow.
luau-wasm is the proof-of-concept: a non-Python language runtime (Luau) compiled to WASM, packaged as a Python wheel, installable via micropip in the browser.
import micropip
await micropip.install("luau-wasm")
import luau_wasm
print(luau_wasm.execute(r'''
local animals = {"fox", "owl", "frog", "rabbit"}
table.sort(animals, function(a, b) return #a < #b end)
for i, name in animals do print(i .. ". " .. name .. " (" .. #name .. ")") end
'''))
The 28 Packages Already Using pyemscripten_202*_wasm32
Simon Willison queried PyPI’s public BigQuery dataset — here’s the early adopter list (most recent first):
| Package | Description | Language |
|---|---|---|
| luau-wasm | Luau language WASM build | Luau |
| uuid7-rs | UUID v7 generator | Rust |
| imgui-bundle | Dear ImGui bindings | C++ |
| geoarrow-rust-core | GeoArrow Rust core | Rust |
| arro3-core / compute / io | Arrow ecosystem | Rust |
| onnx / onnx-weekly | ONNX format support | C++ |
| pydantic_core | Pydantic’s Rust core | Rust |
| typst | Typst typesetting | Rust |
| toml-rs | TOML parser | Rust |
| tcod | Roguelike engine | C++ |
| yaml-rs | YAML parser | Rust |
| cadquery-ocp-novtk-OCP.wasm | CAD kernel | C++ |
| lib3mf-OCP.wasm | 3MF format | C++ |
| robotraconteur | Robot communication | C++ |
| tokie | WASM tokenizer | Rust |
| bashkit | Bash parser | Rust |
| numbertoolkit | Numeric utilities | Rust |
| chonkie-core | Text chunking | Rust |
| powerfit-em | Electron microscopy | C++ |
| pycdfpp | CDF format | C++ |
| cmm-16bit | (undocumented) | — |
| pyOpenTTDAdmin | OpenTTD admin | Rust |
| uuid_utils | UUID utilities | Rust |
| base64_utils | Base64 tools | Rust |
| dummy-pyodide-ext-test | Test package | Python |
| tokio | (duplicate entry?) | Rust |
Notable: The majority are Rust crates compiled via wasm32-unknown-emscripten — the pyemscripten platform tag is becoming the de facto standard for Rust-to-Pyodide distribution.
How to Build Your Own pyemscripten Wheel
- Add
cibuildwheelto your GitHub Actions workflow - Configure platform:
CIBW_PLATFORM="emscripten"(orCIBW_ARCHS_WASM32="wasm32") - Set build frontend: Ensure
pyproject.tomlhas[build-system]withrequires = ["setuptools", "wheel", "cibuildwheel"] - Publish to PyPI — the wheel gets the
pyemscripten_2026_0_wasm32tag automatically
Simon’s luau-wasm repo has a complete, minimal example — including the HTML demo page that loads Pyodide, installs the package, and provides an interactive editor.
What This Unlocks
| Use Case | Why It Matters |
|---|---|
| Language runtimes in browser | Lua, Python, Rust, WASM-native runtimes — no server needed |
| Interactive docs / playgrounds | Real code execution in documentation (see Typst, ONNX demos) |
| Edge compute / serverless | Pyodide + micropip = instant dependency resolution in Cloudflare Workers, Vercel Edge |
| Scientific Python in browser | NumPy, Pandas, Arrow ecosystem already publishing wheels |
The Catch (June 2026)
- Pyodide 314.0 required — older versions don’t recognize
pyemscriptenplatform tags - WASM32 only — no
wasm64support yet - Binary size matters — 276 KB for luau-wasm is lean; larger crates (arrow, pydantic_core) push 10-50 MB
- Threading / SIMD — limited to what Emscripten + browser exposing; pthreads need COOP/COEP headers
Quick Answers
Can I run this in Node.js / Bun / Deno?
No — luau-wasm targets the Pyodide / Emscripten runtime (WASI-style imports, JS Promise integration). For standalone WASM, compile Luau directly via wasm32-wasi.
Is this “Python in the browser”?
It’s Luau in the browser, distributed via Python packaging tooling. The wheel contains a .wasm binary + Python shim that calls luau_wasm.execute(string).
Why publish a non-Python language as a Python wheel?
Because PyPI + micropip is the most frictionless distribution mechanism for Pyodide. No CDN, no version pinning, no manual fetch — await micropip.install("luau-wasm") just works.
What’s the performance like?
Luau’s JIT is disabled in WASM (no executable memory in browser). Interpreter-only mode — fast enough for scripting, not for heavy compute. See luau.org for native benchmarks.
Source: Simon Willison — “Publishing WASM wheels to PyPI for use with Pyodide” (June 13, 2026); PyPI warehouse PR #19804 (landed April 21, 2026); PEP 783 — PyEmscripten platform.
Live demo: simonw.github.io/luau-wasm/ • Pyodide REPL: pyodide.org/console.html • BigQuery SQL: gist.github.com/simonw/4a34a49fca63bc09c50bc31e17b3d33b
Related: Pyodide 314.0 release notes • How to publish WASM wheels to PyPI • Running Rust in the browser with Pyodide
Quick Answers
Q: Can I run luau-wasm in Node.js / Bun / Deno?
FAQ
Q: Can I run luau-wasm in Node.js / Bun / Deno?
A: No — it targets the Pyodide/Emscripten runtime (WASI-style imports, JS Promise integration). For standalone WASM, compile Luau directly via wasm32-wasi.
Q: Is this “Python in the browser”?
A: It’s Luau in the browser, distributed via Python packaging tooling. The wheel contains a .wasm binary + Python shim calling luau_wasm.execute(string).
Q: Why publish a non-Python language as a Python wheel?
A: Because PyPI + micropip is the most frictionless distribution for Pyodide. No CDN, no version pinning, no manual fetch — await micropip.install("luau-wasm") just works.
Q: What’s the performance like?
A: Luau’s JIT is disabled in WASM (no executable memory in browser). Interpreter-only mode — fast enough for scripting, not heavy compute. See luau.org for native benchmarks.
Q: How do I build my own pyemscripten wheel?
A: Add cibuildwheel to GitHub Actions, set CIBW_PLATFORM="emscripten", configure pyproject.toml build-system, publish to PyPI. Simon’s luau-wasm repo has a minimal working example.
Bottom Line
luau-wasm 0.1a0 proves the PyPI + Pyodide + pyemscripten pipeline works for any language that compiles to WASM. 28 packages (mostly Rust crates) already use it. If you’ve been waiting for a standard way to ship WASM binaries to the browser via pip install, it’s here — and the tooling is cibuildwheel + one GitHub Actions workflow.
