一个把 Python 从服务器扩展到浏览器的神器 -- Pyodide
- PyPI 现在接受一种叫 pyemscripten的 wheel tag——Python 包的浏览器目标平台,和 Linux wheel 同级。
- Simon Willison 用 cibuildwheel 一行 YAML,把 C++ 代码编译成 WASM wheel 传上 PyPI,浏览器里 `import` 直接跑。
- 判断一个"X 语言进 Y 平台"是不是真范式转移,看三信号:协议标准化 + 工具零门槛 + 关键包入局。全亮才是真的。
import luau_wasm
跑了段斐波那契。
整个流程他花了一个下午。
重点不是"Python 能在浏览器跑了"——这件事 2018 年 Pyodide 项目刚启动时就能了。重点是
他怎么做到的
:没有找 Pyodide 团队帮忙,没有用任何私有索引,没有绕任何弯。就是写代码、配 CI、
twine upload
。和发一个 Linux wheel 没区别。
这才是 Pyodide 314.0 真正改变的东西。
01 一个 Wheel,四张面单
.whl
文件,文件名里嵌一个平台 tag——
manylinux_2_17_x86_64
表示给 64 位 Linux 用的,
win_amd64
给 Windows。PyPI 收到上传后,
pip install
的时候根据你的系统选对应的 wheel。这套机制从 PEP 427(2012 年)到现在跑了 14 年,撑起了整个 Python 生态。
但在 PEP 783 之前,WASM 不属于这个体系。
Pyodide 团队手工维护了 300 多个包的独立索引,放在
anaconda.org/pyodide
。每个有 C 扩展的包——numpy、scipy、pydantic-core——都要他们手动交叉编译一遍。包维护者自己不用管浏览器这个 target,也管不了——PyPI 根本不接受 WASM 平台的 wheel。上传就报错。
这就是持续了 6 年的中央化瓶颈:包的原始作者最了解自己的代码,却不能自己发布浏览器版本。Pyodide 团队成了 gatekeeper——不是因为他们想当,是因为基建没跟上。
PEP 783 在 2026 年 4 月 6 号正式被 Python 治理委员会接受,然后事情开始加速。这份 PEP 只做了一件事:定义一个新平台 tag——
pyemscripten_{YEAR}_{PATCH}_wasm32
。看起来就是几个词加下划线,但它是 Python 生态第 14 个被正式承认的 wheel 平台。和
manylinux
、
win_amd64
、
macosx_11_0_arm64
同级。
4 月 21 日,PyPI 合并了 warehouse PR
#19804
,上传通道打开。6 月 7 日,cibuildwheel v4.0 发布,一行 YAML 构建 WASM wheel。6 月 9 日,Pyodide 314.0 发布,版本号从 0.29 直接跳到 314.0——对齐的是 CPython 3.14 的版本号。一个在 0.x 阶段待了 8 年的项目,突然把自己标到了 300+。
这不是突然发生的。这是 7 年基建的收束。但在 2026 年 6 月这两周,所有拼图同时到位了。
02 Simon 的一下午
回到 Simon 的实验。他选了一个巧妙的 demo 对象:Luau。这是 Roblox 开发的一门脚本语言,从 Lua 5.1 fork 出来,加了渐进类型系统和性能优化。用 C++ 写的。Simon 想把它打包成一个可以在浏览器里
import
的 Python 模块。
wasm32-unknown-emscripten
。这和编译到 ARM 或 x86 的逻辑一样,只是目标指令集不同。
第二步:打包成 wheel。
cibuildwheel 自动检测平台 tag,生成这样的文件名:
luau_wasm-0.1a0-cp314-cp314-pyemscripten_2026_0_wasm32.whl
拆开看:
cp314
= CPython 3.14,
pyemscripten_2026_0
= Emscripten 2026 年第 0 版 ABI,
wasm32
= 32 位 WASM 架构。271.6 KB。对,一个完整的脚本语言运行时,不到 300 KB。
第三步:
twine upload
,完。
剩下的步骤和发任何 Python 包一样。
然后 Simon 打开 Pyodide 的在线 REPL,敲了这几行:
import micropip
await micropip.install("luau-wasm")
import luau_wasm
print(luau_wasm.execute('''
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
'''))
输出:按名字长度排好序的四只动物。6 毫秒跑完。在一个浏览器 tab 里。
他还部署了一个 GitHub Pages demo,打开就能玩:左边代码编辑器,右边输出面板,Hello World、斐波那契、运行时错误测试——几个预设按钮,simonw.github.io/luau-wasm。不用装任何东西。
- uses: pypa/cibuildwheel@v4
env:
CIBW_BUILD: "cp314-pyodide_wasm32"
如果是 Rust 写的扩展(通过 PyO3/maturin),需要额外设一个环境变量:
export MATURIN_PYEMSCRIPTEN_PLATFORM_VERSION=2026_0
然后 maturin 会自动选
wasm32-unknown-emscripten
target。Rust 1.93.0 以上不需要 nightly——这是另一个"不是玩具"的信号。一个需要 nightly Rust 的平台是实验性的;一个 stable Rust 能直接编译的平台是生产级的。
Pydantic 的
pydantic_core
(Rust 写的校验核心)v2.47.0 已经作为 pyemscripten wheel 在 PyPI 上了。你可以自己去验证:打开 pypi.org/project/pydantic_core/#files,翻到最下面,能看到
cp314-cp314-pyemscripten_2026_0_wasm32.whl
。和它的 118 个兄弟 wheel 排在一起——Linux 的、macOS 的、Windows 的,现在加了一个浏览器的。
03 谁已经在船上,以及怎么上船
Simon 用 BigQuery 扫了 PyPI 的公开数据集。截止 6 月中旬,已经发布
pyemscripten_202*_wasm32
wheel 的包有这些:
pydantic_core
、
onnx
、
imgui-bundle
、
typst
、
uuid7-rs
、
yaml-rs
、
toml-rs
、
cmm-16bit
、
cadquery-ocp
、
arro3-*
系列……
CIBW_BUILD
。CI 多跑 2-3 分钟。多了几百 KB 的 wheel 文件。覆盖的是什么?一个全新的平台——所有能用浏览器的设备。
这个成本/收益比,随着 cibuildwheel v4.0 的发布,已经偏到了让大多数维护者选择"加"的那一边。
但不是所有包都适合。
04 浏览器里的 Python 能做的事
Pyodide 不是服务器 Python 的替代品。把它当替代品用,你会失望。把它当 浏览器里的 Python 用,它很强。- 零安装教学环境。 学生打开一个 URL,就能在一个完整 Python 环境里写代码、跑结果。JupyterLite 和 marimo 已经在用 Pyodide 服务数十万用户。没有环境配置、没有 IT 审批、没有"老师我的 pip install 报错了"。
- 数据不出浏览器的本地分析。 Stanford 研究员和 NASA 科学家已经在 marimo(基于 Pyodide)上发布可交互 notebook——数据留在用户本地,不上传云端。GDPR 零表面积。对医疗、金融、政府数据场景,这不是 nice-to-have,这是合规前提。
- 交互式文档。 你在读一个 Python 库的文档,旁边就是一个能直接跑代码的 REPL。不是截图,是真的能 import、能报错、能出结果的 Python 环境。这对降低库的试用门槛是降维打击。
-
多线程和 multiprocessing。
浏览器的安全模型从根本上不允许共享内存多线程。SharedArrayBuffer 需要特殊的 HTTP header(COOP/COEP),而且不提供 pthread。如果你的包依赖
threading或multiprocessing——WASM wheel 不是你的战场。 -
随意访问网络。
requests.get("https://任意网址")在浏览器里撞上 CORS 墙。Pyodide 提供pyodide.http包装了浏览器的fetch()API,但它不是requests的直接替换。服务器端得配 CORS header 才行。Node.js 下有实验性 socket 支持(pyodide.useNodeSockFS()),但浏览器端无解。 - 轻量快速启动。 Pyodide 核心运行时 6.4 MB。科学计算栈几十 MB。首载 2-5 秒没有 Service Worker 缓存。不是大问题——浏览器会缓存——但"秒开"是不现实的。
05 从"Python 能在浏览器跑"到"浏览器是一等平台"
2018 年,Pyodide 项目刚启动时的叙事是:"你看,CPython 能在浏览器里跑!"这个叙事在 2026 年 6 月已经过时了。现在的叙事是:" pip install 的第四个平台,叫浏览器。 " 判断一个基础设施变化是不是"范式级别",我有三个简单信号:-
协议标准化了吗?
PEP 783 不是某个公司的产品更新——是 Python 治理流程产出的正式标准。这意味着它不会因为某个团队撤资而消失。平台 tag 一旦进入
pypa/packaging,就是 Python 语言基础设施的一部分。 - 工具链降到零门槛了吗? cibuildwheel v4.0 做到了。一行 YAML,不多不少。不需要理解 Emscripten 版本号、不需要手写 WASM 编译参数、不需要学新 CLI。这个门槛对包维护者的采纳速度是决定性的——从"我需要学新东西"变成"加一行配置,CI 多跑 3 分钟",决策性质完全不同。
- 有"不可能回头"的关键包入局了吗? Pydantic 是第一个。不是某个独立开发者的周末项目,是一个被 FastAPI、LangChain、LlamaIndex 等半个 AI 生态依赖的数据校验核心。它入局意味着 WASM wheel 经过了生产级 Rust 扩展的编译链验证。numpy、scipy、polars 已经在路上。
06 你现在能做的三件事
- 打开你维护的包的 CI 配置。
.github/workflows
里找到 cibuildwheel 的 job,加一行:
CIBW_BUILD: "cp314-pyodide_wasm32"
推上去,看 CI 能不能绿。如果绿了——你的包就有了第四个平台。
- 打开 "https://pyodide.org/en/stable/console.html",在 REPL 里敲:
import micropip
await micropip.install("你常用的包名")
看它能不能装上。能装上 = 包的维护者已经替你做了第 1 步。
- 如果前面两步都不适用——记住这三信号判断框架。
07 📋 发布元数据
生成时间:2026-06-14 · 由 Hook Master + Title Judge 提供
✅ 最终标题
pip install 的第四个平台,叫浏览器 作者: 一个把 Python 从服务器扩展到浏览器的神器 -- Pyodide备选标题
- Python 进浏览器的最后一块拼图,不是技术,是分发
- 你的 Python 包多了一个 target,叫 wasm32
TL;DR(已注入正文开头)
-
PyPI 现在接受一种叫
pyemscripten的 wheel tag——Python 包的浏览器目标平台,和 Linux wheel 同级。 -
Simon Willison 用 cibuildwheel 一行 YAML,把 C++ 代码编译成 WASM wheel 传上 PyPI,浏览器里
import直接跑。 - 判断一个"X 语言进 Y 平台"是不是真范式转移,看三信号:协议标准化 + 工具零门槛 + 关键包入局。全亮才是真的。
核心摘要(≤120 字)
Python 分发的边界不再是 CPU 架构——Pyodide 314.0 将 WASM 变成了 PyPI 上的一等 wheel 目标平台。这不是"Python 能在浏览器跑"的老故事,而是 pip install 机制本身的一次静默升级:PEP 783 标准化平台 tag,cibuildwheel v4.0 把门槛降到一行 YAML,Pydantic 等关键包已入局。本文从 Simon Willison 的可复现实操切入,给出一个三信号判断框架供读者迁移复用。小红书引流文案
家人们,Python 生态发生了一件大事但没人咋呼 📢 pip install 现在有第四个平台了——叫浏览器。不是以前那种"Python 转 JS"的老方案,是正儿八经的 CPython 3.14 编译成 WebAssembly,wheel 直接传 PyPI,浏览器里
import micropip; await micropip.install("包名")
就能用。
Simon Willison(那个 Django 创始人)花一个下午就把他写的 C++ 项目打包成 WASM wheel 传上去了。271 KB。6 毫秒跑完斐波那契。
Pydantic 已经在发了。这意味着什么?以后你在浏览器里跑 Python 不会再有"对不起,这个库不支持"——只要维护者加一行 CI 配置。
我写了篇 3000 字把这事掰开讲清楚了 👆 从 PEP 783 到 cibuildwheel 到 Pyodide 314.0,到谁已经在船上、谁不该上船。诚实画了边界——三件事能做,三件事做不了。
标签:
#Python
#Pyodide
#WebAssembly
#pip
#开源
#技术趋势
#浏览器编程
即刻引流文案
Python 生态一个被低估的大变化:Pyodide 314.0。 不是"Python 能在浏览器跑了"(那个 2018 年就能了),是 PyPI 现在接受 WASM 平台的 wheel 了。和 Linux/macOS/Windows wheel 同级——同一个 twine upload。 Simon Willison 前天写博客验证了全流程:C++ → Emscripten → WASM wheel → PyPI → 浏览器
import
,一个下午跑通。Pydantic 已经在生产级发 emscripten wheel 了。
这不是玩具信号。cibuildwheel v4.0 把门槛压到了一行 YAML。
我写了个判断框架:协议标准化 × 工具零门槛 × 关键包入局 = 范式转移。缺一个就是 demo。
SEO 关键词
- 主关键词 :Pyodide 314.0 WASM wheel PyPI
- 长尾词 :Python 浏览器 运行、pip install WebAssembly、pyemscripten wheel 构建、Pyodide vs Brython、cibuildwheel WASM target、Python 包 浏览器 target、PEP 783 中文 解读
视觉资产
-
fig1 时间线图
:
articles/pending/visuals/2026-06-14-pyodide-3140-wasm/fig1-timeline.md(Pyodide 7 年基建收束,5 个关键拐点) -
fig2 流程图
:
articles/pending/visuals/2026-06-14-pyodide-3140-wasm/fig2-flowchart.md(WASM wheel 完整构建管线) -
fig3 四象限图
:
articles/pending/visuals/2026-06-14-pyodide-3140-wasm/fig3-quadrant.md(浏览器 Python 方案竞争定位) -
fig4 外部截图
:
articles/pending/visuals/2026-06-14-pyodide-3140-wasm/配图说明.md(5 张手动截图优先级清单)
标签: #Python #Pyodide #WASM