macintosh.world | Log In | Register
Today | News | Books | Recipes | Notes | YouTube | QuickTake
Translate | Wiki | Browse | Maps | Reference | Reddit | About

Back to HN

Pyodide 314.0: Python packages can now publish WebAssembly wheels to PyPI

by agriyakhetarpal | 94 points | 22 comments | 2026-06-09 10:54:31 Central

Open Source Link | Read Source Here

Open on Hacker News

Comments

simonw
I've been looking forward to this for ages!This means we
can now take any C/Rust/whatever extension for Python,
compile that as a `.wasm` extension, and then load it
directly in browser Pyodide projects using: await
micropip.install("package-on-pypi")
import package_name

Here's how to try the new feature out. Visit
https://pyodide.org/en/stable/console.html and type:
import micropip
await micropip.install("pydantic_core")
import pydantic_core

That gets you this WASM wheel:
https://pypi.org/project/pydantic_core/#pydantic_core-2.47
.0...You can tell that it's got compiled code in (and not
just Python) by running: pydantic_core._pydantic_core

I get this: <module 'pydantic_core._pydantic_core' from
'/lib/python3.14/site-packages/pydantic_core/_pydantic_cor
e.cpython-314-wasm32-emscripten.so'>

  > simonw
I had an older experimental Pyodide WASM project lying
around (a packaging of the Luau language by Roblox) so
I had Codex package that up for me and pushed it to
PyPI.Here's the package:
https://pypi.org/project/luau-wasm/ 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
'''))

And an interactive demo page where you can try it out:
https://simonw.github.io/luau-wasm/Wrote about this in
more detail on my blog:
https://simonwillison.net/2026/Jun/13/publishing-wasm-
wheels...

  > rtpg
Is there any form of client-side caching that kicks in
with all of this flow?Tbh I don't feel great about
people just writing up a bunch of scripts pulling
things just on every run.

    > > simonw
Browser caching works with stuff pulled from PyPI,
so it shouldn't get loaded more than once.

  > willXare
`await micropip.install()` is starting to feel
dangerously close to "just ship the whole universe to
the browser."

12_throw_away
Executing normal python programs inside a cpython vm
inside a wasm context inside a javascript process inside a
sandbox inside a browser is - genuinely - extremely
exciting! (Might as well run the browser inside a
container inside a VM while you're at it though.)

  > apitman
I'm sure everyone has seen this by now but just in
case:
https://www.destroyallsoftware.com/talks/the-birth-and
-death...

  > willXare
We heard you like runtimes, so we put a runtime in
your runtime inside your runtime.

  > rvz
This sounds like a solution looking for an unnecessary
security nightmare.Something as little as the runtime
can just get exploited (which that as happened.) and
cause a sandbox escape on the client side. There was a
Chrome 0day at the runtime level which allowed
untrusted code to run and escape the sandbox in the
WASM runtime.This complete worship of WASM (and their
runtimes) as this magical silver bullet reminds me of
the days and failures of Native Client (NaCL), Java
Applets and Flash all over again.

    > > simonw
You mean this one?
https://theori.io/blog/a-deep-dive-into-v8-sandbox
-escape-te...I dunno, one sandbox escape in nine
years is a pretty solid track record IMO.Any
reason WASM is more dangerous than regular
JavaScript?

      > > > rvz
No. This one. [0].Even before that, there are
several other sandbox escapes that predated
the one you posted. [1] [2] and this one [3]
can be used to trivially escape its sandbox
with either of these vulnerabilities.So it is
not the magical silver bullet one may easily
think it is.[0]
https://nvd.nist.gov/vuln/detail/CVE-2026-1164
5[1]
https://blog.ret2.io/2021/06/02/pwn2own-2021-j
sc-exploit/[2]
https://issues.chromium.org/issues/40091185[3]
https://phrack.org/issues/72/10_md#article

zek
I've been working on a server-side wasm impl of cpython
called boomslang [1] and have been thinking a lot lately
about packaging, one of the downsides of my current impl
is the need to statically link all c/rust extensions. Its
too bad IMO how much of the wasm ecosystem targets/depends
on emscripten directly. It'd be interesting to see if a
more generic ABI could be provided for non emscripten/js
based wasm runtimes.[1]
https://github.com/HubSpot/boomslang

  > DarkUranium
I think one of the issues is that WASM is notoriously
hard to generate code for because they decided to use
an IR that's fundamentally incompatible with literally
any existing native compiler backend's IR (not
counting very specialized ones or toy
direct-ast-to-machine-code compilers).It feels like
nobody actually consulted actual compiler writers when
designing this. I'm sure that isn't true, but it
definitely feels that way. (I suspect the truth is
that they were consulted, but ignored.)It means
codegen needs to resort to all sorts of hacks (like
the relooper) in order to target WASM, a property not
shared by any other target.And apparently, the way
they handle variables also results in deoptimization,
though I don't recall the details of that.Add the fact
that interacting with the browser on the web still has
to go via JavaScript to this day (for the most part,
at least), and, well.---TL;DR a combination of poor IR
design that has a massive impedance mismatch with
pre-existing compilers (and most new ones, because it
turns out there's a reason the WASM approach isn't
standard) plus WASM still being a second-class citizen
in its supposed primary environment (the 'W' in WASM)
--- the former ensures targeting it consumes a lot of
resources/time, the latter ensures the bar for that to
be worth it is much higher.You can target most
architectures with little trouble (at least a a
baseline --- optimization's a hard problem regardless
of target, except maybe SPIR-V due to the
recommendation that pre-optimization is limited in
scope). But WASM is completely out there, it's closer
to trying to target e.g. Java (not JVM!) at the
backend instead of machine code or some other IR.You
don't make an IR intended to be targeted by
existing/native compilers by making it completely
different to anything they had to target before and
completely different to their own IRs and
representations ... unless you're the guys behind
WASM.

    > > ameliaquining
I don't think the controversy about Wasm's
structured control flow has anything to do with
any of this? It's not actually difficult to target
Wasm in codegen; I've never heard of any
real-world compiler project complaining that this
was a major burden. ABI concerns are at a
different level.Most low-level IRs don't do
structured control flow because most low-level IRs
don't need to be translatable to verified-safe
machine code in a single fast pass, whereas for
WebAssembly that's a core design requirement.

    > > hmry
From what I remember, it was specifically chosen
(among other reasons) because of experience with
the JVM, where it was difficult to verify bytecode
type-safety due to unrestricted jumps and
branches.So the choice was made to put the burden
of regularizing the control flow on the compilers
at compile time, rather than the browser engine at
website load time. Which seems rational to me.

willXare
Python in the browser keeps sounding ridiculous right up
until it works.

wolfgangK
I presume this works (will work) also for JupyterLite that
is based on Pyodide ?
Would be great if it helped getting the latest
OpenCV-python version [0] and it's dnn goodies being
available on a zero-install client side Notebook ![0]
https://news.ycombinator.com/item?id=48421858

  > simonw
Yeah it should definitely work there, anything you can
`micropip.install()` into a Pyodide environment will
work with JupyterLite.

fzumstein
Pyodide 314.0 is already available in xlwings Lite (the
Python in Excel alternative you actually wanted).

efromvt
Fantastic to have PyO3/Maturin guides too - the
rust/python/typescript turducken I've always wanted.

runningmike
Great news. And indeed a nice step to an even broader
Python ecosystem.

sgammon
nice to see JS/python interop becoming a thing