Simon Willison · Tech & AI
TIER 4 2026-06-13
<p>The <a href="https://blog.pyodide.org/posts/314-release/">Pyodide 314.0 release announcement</a> (via <a href="https://news.ycombinator.com/item?id=48462759">Hacker News</a>) includes news I've been looking forward to for a long time:</p>
<blockquote>
<p>You can now publish Python packages built for Pyodide (or any Python runtime compatible with <a href="https://pyodide.org/en/stable/development/abi.html">the PyEmscripten platform defined in PEP 783</a>) directly to PyPI and install them at runtime.</p>
<p>Previously, the Pyodide maintainers had to maintain, build, and host over 300 packages ourselves. This created a significant burden on our maintainers and became a major bottleneck for the community, as every new package required manual review.</p>
<p>Moving forward, package maintainers can simply build and publish Pyodide wheels to PyPI, just as they do for native wheels on Linux, macOS, or Windows.</p>
</blockquote>
<p>Here's the <a href="https://github.com/pypi/warehouse/pull/19804">PR to PyPI itself supporting this</a>, which landed on April 21st.</p>
<p>I adore <a href="https://pyodide.org">Pyodide</a>, and have been frustrated in the past by this limitation. It's possible to compile C or Rust extensions to WASM in a wheel file, but before now there was no easy way to distribute them.</p>
<p>Thanks to the efforts of a whole lot of people, that's now been fixed!</p>
<h4 id="trying-it-out-with-luau-wasm">Trying it out with luau-wasm</h4>
<p>I decided to celebrate by finding something I could package. I have quite a few experimental Pyodide projects lying around, but the best fit for this looked to be my <a href="https://github.com/simonw/research/tree/main/pluau-wasm-pyodide#readme">Luau WebAssembly research spike</a> from 9th March.</p>
<p><a href="https://luau.org">Luau</a> is a "small, fast, and embeddable programming language based on Lua with a gradual type system", <a href="https://luau.org/news/2022-11-04-luau-origins-and-evolution/">developed by Roblox</a> and released under an MIT license.</p>
<p>It's written in C++. I already knew it was possible to compile it to WebAssembly and get it running inside of Pyodide, so I <a href="https://gist.github.com/simonw/1761eab6ba11d4053f56f955a28ad76b">set Codex + GPT-5.5 xhigh</a> the task of packaging my experiment up and publishing it to PyPI using GitHub Actions.</p>
<p>It took some iteration, but here's the result: <a href="https://pypi.org/project/luau-wasm/">luau-wasm</a> is a brand new PyPI package which publishes a 276KB <code>luau_wasm-0.1a0-cp314-cp314-pyemscripten_2026_0_wasm32.whl</code> file which can be used in Pyodide like this:</p>
<pre><span class="pl-k">import</span> <span class="pl-s1">micropip</span>
<span class="pl-k">await</span> <span class="pl-s1">micropip</span>.<span class="pl-c1">install</span>(<span class="pl-s">"luau-wasm"</span>)
<span class="pl-k">import</span> <span class="pl-s1">luau_wasm</span>
<span class="pl-en">print</span>(<span class="pl-s1">luau_wasm</span>.<span class="pl-c1">execute</span>(<span class="pl-s">r'''</span>
<span class="pl-s">local animals = {"fox", "owl", "frog", "rabbit"}</span>
<span class="pl-s">table.sort(animals, function(a, b) return #a < #b end)</span>
<span class="pl-s">for i, name in animals do print(i .. ". " .. name .. " (" .. #name .. ")") end</span>
<span class="pl-s">'''</span>))</pre>
<p>You can run that code <a href="https://pyodide.org/en/stable/console.html">in the Pyodide REPL demo</a> to see it in action.</p>
<p>The <a href="https://github.com/simonw/luau-wasm">GitHub repo for luau-wasm</a> includes all of the build and deploy scripts (using the latest <a href="https://github.com/pypa/cibuildwheel">cibuildwheel</a>) and also deploys an HTML demo page which loads Pyodide, installs <code>luau-wasm</code> and provides an interface for trying it out: <a href="https://simonw.github.io/luau-wasm/">https://simonw.github.io/luau-wasm/</a></p>
<p><img src="https://static.simonwillison.net/static/2026/luau-wasm.jpg" alt="Screenshot of a web app titled "Luau WASM" with subtitle "Run Luau in the browser through Pyodide after installing the luau-wasm WebAssembly wheel from PyPI." A green "Ready" status badge is at top right. Below are example buttons: "Hello World", "Variables", "Tables", "Fibonacci", "Runtime Error". A "LUAU SOURCE" code editor contains: local function fib(n: number): number / if n < 2 then return n end / return fib(n - 1) + fib(n - 2) / end / local out = {} / for i = 0, 12 do / table.insert(out, tostring(fib(i))) / end / print(table.concat(out, ", ")). On the right is an "OUTPUT" panel with a "Copy" button showing dark terminal output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144. At the bottom left are a blue "Run" button, a "Clear" button, and the text "6.0 ms"." style="max-width: 100%;" /></p>
<h4 id="how-many-packages-are-using-this-so-far-">How many packages are using this so far?</h4>
<p>I was curious to see how many packages are currently publishing wheels for this platform.</p>
<p>After some <a href="https://chatgpt.com/share/6a2dee92-b110-83e8-9f53-ba9259b751ed">tinkering with ChatGPT</a> I got to <a href="https://gist.github.com/simonw/4a34a49fca63bc09c50bc31e17b3d33b?permalink_comment_id=6198602#gistcomment-6198602">this BigQuery SQL</a> which I ran against PyPI's <a href="https://packaging.python.org/en/latest/guides/analyzing-pypi-package-downloads/#public-dataset">public dataset on BigQuery</a>. Here's the <a href="https://gist.github.com/simonw/4a34a49fca63bc09c50bc31e17b3d33b">raw JSON</a> of query results and here's a SQLite SQL query <a href="https://lite.datasette.io/?json=https://gist.github.com/simonw/4a34a49fca63bc09c50bc31e17b3d33b#/data?sql=select%0A++name%2C%0A++platform_tag%2C%0A++matching_file_count%2C%0A++max%28latest_upload%29+as+latest_upload%2C%0A++example_files%0Afrom+%28%0A++--+your+existing+query+here%2C+without+order+by%0A++select%0A++++name%2C%0A++++platform_tag%2C%0A++++matching_file_count%2C%0A++++latest_upload%2C%0A++++example_files%0A++from+raw%0A%29%0Agroup+by+name%0Aorder+by+latest_upload+desc%3B">in Datasette Lite</a> which dedupes packages by most recent upload date.</p>
<p>If the query is right, there are currently 28 PyPI packages publishing with the new <code>pyemscripten_202*_wasm32</code> tags:</p>
<p><a href="https://pypi.org/project/luau-wasm/">luau-wasm</a>, <a href="https://pypi.org/project/uuid7-rs/">uuid7-rs</a>, <a href="https://pypi.org/project/cmm-16bit/">cmm-16bit</a>, <a href="https://pypi.org/project/pyOpenTTDAdmin/">pyOpenTTDAdmin</a>, <a href="https://pypi.org/project/imgui-bundle/">imgui-bundle</a>, <a href="https://pypi.org/project/numbertoolkit/">numbertoolkit</a>, <a href="https://pypi.org/project/bashkit/">bashkit</a>, <a href="https://pypi.org/project/geoarrow-rust-core/">geoarrow-rust-core</a>, <a href="https://pypi.org/project/arro3-io/">arro3-io</a>, <a href="https://pypi.org/project/arro3-core/">arro3-core</a>, <a href="https://pypi.org/project/arro3-compute/">arro3-compute</a>, <a href="https://pypi.org/project/onnx/">onnx</a>, <a href="https://pypi.org/project/powerfit-em/">powerfit-em</a>, <a href="https://pypi.org/project/tcod/">tcod</a>, <a href="https://pypi.org/project/chonkie-core/">chonkie-core</a>, <a href="https://pypi.org/project/tokie/">tokie</a>, <a href="https://pypi.org/project/robotraconteur/">robotraconteur</a>, <a href="https://pypi.org/project/pydantic_core/">pydantic_core</a>, <a href="https://pypi.org/project/yaml-rs/">yaml-rs</a>, <a href="https://pypi.org/project/cadquery-ocp-novtk-OCP.wasm/">cadquery-ocp-novtk-OCP.wasm</a>, <a href="https://pypi.org/project/uuid_utils/">uuid_utils</a>, <a href="https://pypi.org/project/base64_utils/">base64_utils</a>, <a href="https://pypi.org/project/pycdfpp/">pycdfpp</a>, <a href="https://pypi.org/project/lib3mf-OCP.wasm/">lib3mf-OCP.wasm</a>, <a href="https://pypi.org/project/typst/">typst</a>, <a href="https://pypi.org/project/toml-rs/">toml-rs</a>, <a href="https://pypi.org/project/onnx-weekly/">onnx-weekly</a>, <a href="https://pypi.org/project/dummy-pyodide-ext-test/">dummy-pyodide-ext-test</a></p>
<p>Here's hoping we see a whole lot more of those showing up over the coming months and years.</p>