Bun v1.4.1 深度解析:从 Zig 到 Rust,一场 11 天、64 个 AI 代理的语言迁徙

文章来源声明: 原文作者:iDao技术魔方; 来源站点:掘金; 原文链接:https://juejin.cn/post/7684463933718822939; 本文基于上述来源整理/加工,觅优补充点评,仅供技术学习交流。版权归原作者所有。
觅优短评

对关注 AI 辅助大规模重构与运行时选型的团队,这篇复盘值得细读:它提醒我们别把语言当性能银弹,也别忽视 AI 生成代码的审查成本与 unsafe 风险。

> 2026 年 9 月 4 日,Bun 发布 v1.4.1。表面上看,这是一次常规的补丁更新——修复 202 个问题,引入 HTTP/2 支持、pausable WebSocket、crypto.argon2、9x 加速的 Buffer 读写。但如果你把目光移到这个版本号的背后,会发现一件远比补丁更震撼的事情:**Bun 的运行时核心,已经从 Zig 彻底重写为 Rust**。 > > 这是 JavaScript 运行时历史上规模最大、最仓促、也最具争议性的一次语言迁移。

一、Bun v1.4.1 说了什么?

先看这个版本的核心变化。按影响力排序:

闲置内存回收:JIT 代码的"自杀式"优化

JavaScriptCore 现在会在进程闲置一段时间后,删除 JIT 生成的机器码。这意味着一个 Next.js SSR 应用在负载后闲置 3 分钟,RSS 从 1,303 MB 骤降至 142 MB——降幅接近 11 倍

这不是魔法,而是 JSC 的 LLInt → Baseline JIT → DFG → FTL 四级编译管道在闲置时被主动清空。V8 不会这么做:它为长驻留进程设计,JIT 热代码会一直保留。Bun 反其道而行——"用完即焚",因为它的目标场景包括 CLI 工具、Serverless 函数和短生命周期进程。

<span>Bun</span> v1.<span>4.1</span> 闲置内存基准(<span>Linux</span> x64,60s 负载 + <span>3</span> 分钟空闲):

|<span> 应用        </span>| <span>Bun</span> v1.<span>4.1</span> |<span> Bun v1.4.0 </span>| <span>Bun</span> v1.<span>3.14</span> |<span> Node.js v26 </span>|
|<span>-------------</span>|-----------<span>:|-----------</span><span>:|------------</span><span>:|------------</span><span>:|</span>
|<span> Next.js SSR </span>|    <span>142</span> <span>MB</span>  |<span>    222 MB  </span>|    <span>1</span>,<span>303</span> <span>MB</span> |<span>      195 MB </span>|
|<span> vite dev    </span>|    <span>111</span> <span>MB</span>  |<span>    142 MB  </span>|      <span>292</span> <span>MB</span> |<span>      115 MB </span>|
|<span> Express     </span>|     <span>53</span> <span>MB</span>  |<span>     65 MB  </span>|       <span>76</span> <span>MB</span> |<span>       83 MB </span>|
|<span> Fastify     </span>|     <span>55</span> <span>MB</span>  |<span>     65 MB  </span>|       <span>78</span> <span>MB</span> |<span>       89 MB </span>|
|<span> Hono        </span>|     <span>34</span> <span>MB</span>  |<span>     35 MB  </span>|       <span>53</span> <span>MB</span> |<span>       92 MB </span>|

HTTP/2 首次入原生运行时

Bun.serve 现在在同一端口上同时支持 HTTP/2 和 HTTP/1.1——通过 ALPN 协商。基准测试显示,Bun 的 HTTP/2 实现比 Node.js 的 node:http2 快 6.8 倍(Hello World GET:291,512 vs 55,619 req/s)。

但真正的故事不在这里。

Bun.write(path, response):流式写盘

Bun.write() 现在直接将 ResponseRequestReadableStream 体写入磁盘,而不是先读入内存。写入一个 128 MiB 的下载,峰值 RSS 从 161 MB 降至 13 MB。

这是一个架构选择:它意味着 Bun 的 I/O 路径设计从一开始就考虑了零拷贝和背压,而不是事后修补。

其余关键变化

  • WebSocket pause()/resume():WHATWG WebSocket API 无法暂停接收消息而不关闭连接。Bun 扩展了这个 API,允许在消息到达速度快于处理速度时施加 TCP 背压。
  • crypto.argon2:Argon2 密码哈希现在原生支持,输出与 Node.js 逐字节一致。
  • Buffer 读写 9x 加速writeFloatLE() 从 2.85ns 降至 0.31ns——JIT 内联边界检查后的直接加载/存储。
  • bun build --compile --bytecode 跨平台交叉编译:字节码缓存格式现在在所有平台一致,Claude Code 的安装包从 376 MB 缩减到 207 MB(-45%)。

二、但真正的头条不在上面

Bun v1.4.1 发布 13 天前,Bun v1.4.0 于 2026 年 8 月 20 日发布。这是第一个用 Rust 写的 Bun,也是最后一个用 Zig 写的 Bun(v1.3.14)之后的第一个版本。

时间线:

日期事件
2026-05-13Bun v1.3.14 发布,最后一个 Zig 版本的运行时
2026-05-14Rust 端口合并到 `main` 分支
2026-05-14 ~ 08-203 个月沉默期,修复回归
2026-08-08Jarred Sumner 发布《Rewriting Bun in Rust》
2026-08-20Bun v1.4.0 发布,Rust 运行时首次稳定
2026-09-04Bun v1.4.1 发布,202 个问题修复

从最后一份 Zig 代码到稳定版 Rust 运行时,只用了 11 天。 不,准确地说——是 64 个 Claude 代理并发工作了 11 天,留下了 6,778 个提交和一个超过 100 万行代码的 diff。


三、为什么是 Zig?——Bun 的原始选择

要理解为什么这场迁移如此震撼,需要回到 Bun 的起点。

Zig 的诱惑

Bun 的创造者 Jarred Sumner 在 2021 年选择 Zig 作为运行时语言,绝非偶然。Zig 有几个特性精准命中了 Bun 的设计需求:

  1. 手动内存管理,没有隐藏控制流:没有 GC 暂停,没有异常展开(exception unwinding),每一笔分配都清晰可见。这对追求极致性能的 HTTP 服务器至关重要。
  2. C 互操作性一等公民:Bun 需要嵌入 JavaScriptCore(C++),Zig 与 C 的互操作比 Rust 更直接。
  3. comptime(编译时计算):零成本抽象,可以在编译期做大量工作而不运行时付费。
  4. 错误处理模型error union 强制开发者处理所有可能的失败路径,没有 try/catch 的运行时开销。

Bun 的架构因此分成两层:

  • JavaScriptCore(C++):执行 JavaScript 字节码
  • Zig 运行时:HTTP 服务器、包管理器、文件系统、I/O 层

Zig 运行时替代了 Node.js 的 libuv。直接使用 Linux 的 io_uring(内核 5.1+ 的异步 I/O 接口)、macOS 的 kqueue,绕过线程池的传统瓶颈。

Bun 原始架构(v1.3.14 及之前):

┌──────────────────────────────┐
│       JavaScriptCore          │  ← C++,Safari 的 JS 引擎
│  (LLInt / Baseline / DFG/FTL) │
└──────────┬───────────────────┘
           │
┌──────────▼───────────────────┐
│       Zig 运行时              │  ← 手动内存管理
│  ┌─────────────────────────┐ │
│  │ io_uring / kqueue      │ │  ← 原生异步 I/O
│  │ arena allocators       │ │  ← 每请求分配批量释放
│  │ HTTP 服务器 / 包管理器  │ │
│  │ bun build / bun <span>test</span>   │ │
│  └─────────────────────────┘ │
└──────────────────────────────┘

这个架构在性能上取得了惊人的成功。Bun 的冷启动速度、包管理器速度、测试运行速度都远超 Node.js。

但问题也随之而来。

Zig 的代价

手动内存管理是双刃剑。Bun 的代码库中,use-after-free 和 double-free 漏洞如影随形。正如 Jarred Sumner 在《Rewriting Bun in Rust》中所写:

"历史上,语言重写是个糟糕的主意。Bun 不含注释有 535,496 行 Zig 代码。用另一种语言重写需要一个小团队工程师花一整年。这意味着冻结 bug 修复、安全补丁和功能开发整整一年。"

但 Anthropic 在 2025 年 12 月收购了 Bun。资金充裕,AI 工具成熟,窗口期打开。


四、为什么转向 Rust?——内存安全的诱惑

Rust 的核心卖点是所有权模型:编译器在编译期保证内存安全,没有 GC,没有 use-after-free,没有数据竞争。

对于 Bun 来说,这个迁移的理由很明确:

  1. 消除内存安全漏洞:Zig 的 use-after-free 和 double-free 问题在长期运行的服务中尤其危险。Rust 的所有权模型在编译期捕获这类错误。
  2. 更好的并发原语:Rust 的 Send + Sync trait 在类型层面保证了线程安全。
  3. 生态系统:Rust 的 crate 生态在系统编程领域已经相当成熟。

但这里有一个关键争议——性能是否因此提升?

性能争议的罗生门

Bun 官方将 2-5% 的速度提升归因于跨语言链接时优化(LTO)——Rust 和 C++ 引擎之间的链接优化。但 Andrew Kelley(Zig 语言的创造者)在 2026 年 7 月 9 日发表了尖锐批评:

"性能提升归因于 LTO,而 Zig 在 Bun 的整个生命周期中都支持 LTO。"

独立开发者 Dennis Morello 进一步指出:

"2-5% 的速度提升和约 20% 更小的二进制文件,来自跨语言 LTO、ICU 裁剪和链接器工作——这些在 Zig 中也能做到,不是 Rust 语言的功劳。"

真正的大幅性能提升——闲置 CPU 降低 5 倍、内存降低 13-48%——来自另一个变化:将 JavaScriptCore 统一到 mimalloc 分配器,取代了之前 libpas 和 mimalloc 并行的方案。这不是语言选择的功劳,而是内存分配策略的优化。

换句话说:Rust 迁移的性能收益被夸大了,真正的原因是架构调整和内存管理优化。


五、64 个 Claude 代理的 11 天

这是整个故事中最超现实的章节。

Jarred Sumner 披露:

  • 64 个 Claude 代理并发工作
  • 11 天完成端口
  • 6,778 个提交
  • +1,009,272 行 diff
  • 约 $165,000 的 API token 花费
  • 19 个已知回归,全部已修复

端口的方法论是"强制代码风格":不是纯粹的机械翻译,而是用代码风格规则确保生成的 Rust 代码行为一致。测试套件是唯一的真理标准——所有平台、所有测试通过,零跳过。

开发者 Tero Piirainen 在发布前审查了仓库,发现:

  • robobun 账户单月 15,800 个提交
  • 自动修复机器人 1,600 个提交
  • Bun 负责人 790 个提交
  • 超过 5,000 个开放 PR

他还指出,Rust 代码中约 4% 包含 unsafe 块——约 13,000 个 unsafe 关键字分布在约 27,000 行代码中。如果 4% 的代码是不安全的,那"内存安全"的叙事还剩多少说服力?

这是整个迁移中最深刻的悖论:为了内存安全而重写的代码,仍然需要 unsafe 来突破安全边界。


六、Bun 的技术架构:JavaScriptCore + Rust

理解 Bun v1.4.1 的关键,是理解它的分层架构没有改变:

Bun v1<span>.4</span><span>.1</span> 架构:

┌────────────────────────────────────┐
│         JavaScriptCore             │  ← 未变,C++ 引擎
│  (约 <span>400</span> 个上游 WebKit 提交)        │
│  LLInt / Baseline / DFG / FTL      │
└──────────────┬─────────────────────┘
               │
┌──────────────▼─────────────────────┐
│         Rust 运行时                │  ← 从 Zig 迁移
│  ┌──────────────────────────────┐  │
│  │ HTTP 服务器 (Bun.serve)      │  │  ← io_uring + epoll/kqueue
│  │ bun install (包管理器)       │  │  ← 全局缓存 + 硬链接
│  │ bun build (打包器)           │  │  ← 基于 esbuild 的 Rust 重写
│  │ bun test (测试运行器)        │  │  ← Jest 兼容
│  │ bun:sqlite / bun:redis       │  │  ← 内置客户端
│  │ 文件系统 / I/O 层            │  │  ← 零拷贝路径
│  └──────────────────────────────┘  │
│                                     │
│  ⚠️ 约 <span>4%</span> unsafe 块               │
└────────────────────────────────────┘

JavaScriptCore 本身没有变。变的是围绕它的运行时层:HTTP 服务器、包管理器、打包器、测试运行器、文件系统层——所有用 Zig 写的都换成了 Rust。


七、Bun vs Node.js vs Deno:2026 年的运行时三国杀

维度Bun v1.4.1Node.js 26Deno
JS 引擎JavaScriptCoreV8V8
运行时语言**Rust**C++Rust
Node 兼容目标Node 26.3.0完整部分
`NODE_MODULE_VERSION`147147-
包管理器内置 `bun install`npm`deno`
打包器内置 `bun build`外部外部
测试运行器内置 `bun test``node:test``deno test`
数据库客户端内置 (PG/MySQL/SQLite/Redis)外部外部
冷启动~5ms~50ms~30ms
闲置内存**最低**中等中等
原生插件部分 N-API完整有限
LTS30 个月
企业背书**Anthropic**OpenJS Foundation独立

关键洞察:

  1. Bun 和 Deno 现在都是 Rust,但 Bun 选择了 JavaScriptCore 而不是 V8。这才是性能差异的主因,不是语言本身。
  2. Node.js 26 进入了 LTS(2026 年 10 月至 2029 年),这是保守派的选择。
  3. Bun 的 Node 兼容度已接近可用node:eventsnode:trace_eventsnode:sqlite 100% 通过 Node 官方测试,node:httpnode:fs 等核心模块约 97%。但那剩下的 3% 恰恰是最棘手的问题。

八、深度思考:AI 辅助重写是未来还是危险先例?

Bun 的 Rust 迁移打开了一个潘多拉魔盒。

如果 64 个 AI 代理能在 11 天内完成一个运行时核心的语言迁移,那么:

  • 软件工程的生产力边界在哪里?
  • 代码审查的意义是什么?(19 个回归——AI 生成的代码需要人来发现)
  • "AI 程序员"和"AI 编码助手"的区别是什么?

Jarred Sumner 的回应很诚实:

"这次重写引入了 19 个已知回归,每一个都已修复。聚焦于稳定性是目标,但如此庞大的变更不可能零回归。"

更有趣的是 Claude Code 本身——Anthropic 的编程工具——已经用 Bun 的 Rust 端口在生产环境中运行。它的 p99 CPU 从 24% 降至 10%。

**Anthropic 收购 Bun → 用 Claude 重写 Bun → Claude Code 在 Bun 上运行 → Bun 的性能数据证明 Anthropic 的技术栈优势。**这是一个闭环。


九、总结:这篇 v1.4.1 文章的真正意义

Bun v1.4.1 的 202 个修复看起来像是一次常规更新。但如果你理解了 11 天前那场语言迁徙的规模和争议,就会明白:

  • 闲置内存回收不是 Bug 修复,是架构选择的结果——JavaScriptCore 的 JIT 代码按需生成和销毁,这是 Bun 从一开始就坚持的设计哲学。
  • HTTP/2 原生支持是 Rust 运行时带来的新能力,因为 Zig 版本的代码库在迁移期间被冻结,新 API 只能在新的 Rust 代码上实现。
  • Bun.write() 流式写盘反映了底层 I/O 路径的重构——Rust 的异步模型让零拷贝管道更容易实现。
  • 跨平台字节码交叉编译是 Rust 平台的统一格式带来的红利——字节码缓存格式现在在所有平台一致。

Bun v1.4.1 的每一个技术亮点,背后都有 Rust 迁移的影子。

而更宏大的叙事是:JavaScript 运行时已经不再是 C++ + V8 的天下。Rust + JavaScriptCore 的组合正在挑战 Node.js 的王座,代价是 4% 的 unsafe 和 19 个已知回归。

这是 2026 年最精彩的系统编程故事。


原创技术博客 · 开源项目架构深潜 · idao.fun

image.png