53 万行 Zig、11 天、1 个模型——这是基础设施软件第一次被 AI 系统性地重写 。——Jarred Sumner / Bun 创始人
2026 年 7 月,Bun 创始人 Jarred Sumner 公布了一组让整个 JavaScript 圈沉默的数据: 53 万行 Zig → 11 天 Rust 重写 → 100 万行新增代码被接受合并 。这不是一次普通的技术升级,而是一次 用 AI 模型系统性地重写一门基础设施软件 的完整工程复盘。
本文看点
01
53 万行 Zig 重写的 14 个 use-after-free
02
11 天 + 50 个动态 workflow
03
对抗式 review 与基础设施的未来
01
WHY RUST, NOT ZIG
为什么 Bun 要把自己用 Rust 重写一遍?
Bun 现在的 CLI 每月下载量超过 2200 万次, Claude Code 和 OpenCode 把 Bun 当成默认 runtime ,Vercel / Railway / DigitalOcean 都已经把 Bun 列为 first-party 支持。
但 Bun 的 scope 一直是 稳定性问题 的根源。Bun v1.3.14 这次修的 bug 列表非常典型,几乎全是 使用后释放(use-after-free)、双重释放(double-free)、忘记释放 这类内存安全问题:
BUG LIST · BUN V1.3.14
· `node:zlib` 在异步 `.write()` 还没跑完时调用 `.reset()` 触发 heap-use-after-free
· node:http2 在 hashmap 扩容时让回调拿到失效的 stream 指针
· `UDPSocket.send()` 在 `valueOf()` 回调里 detach ArrayBuffer 导致 payload 失效
· `Buffer#copy` / `Buffer#fill` 在 `valueOf()` 回调里 resizes 底层 buffer
· crypto.scrypt 在分配失败时既不释放回调也不释放 password/salt buffer
· `tlsSocket.setSession()` 每次泄漏一个 \~6.5 KB 的 SSL_SESSION
· `fs.watch()` 的 watcher 引用计数下溢后被永久 pin 在 GC root 上
· `tls.connect({ socket: duplex })` 的 DuplexUpgradeContext 永远不释放
这些问题在 Bun v1.3 的 14 个 changelog 里有 11 个。Bug 列表越修越长,Sumner 自己都说"晚上睡觉都在担心 Bun 什么时候 crash"。
Bun 已经在做的稳定性防御
给 Zig 编译器打补丁加上 Address Sanitizer(ASAN),每个 commit 跑一遍测试套件;Windows ReleaseSafe build 默认开启 Zig safety 检查; 24/7 用 Fuzzilli fuzz runtime API (Fuzzilli 是 Google Project Zero 用来 fuzz V8 和 JavaScriptCore 的工具);一大堆端到端的内存泄漏测试。
但这些防御仍然不够。 use-after-free / double-free / forgot-to-free 这三类 bug ,本质是 Zig 内存管理模型的必然产物 。
02
THE DEFER PROBLEM
Zig 的 defer 不是终极答案
Zig 是 Bun 创立时的核心赌注。Sumner 在 2021 年 4 月 16 日写下第一行 Zig 代码 时,Bun 是 esbuild Go → Zig 的一行一行移植。他选择 Zig 的理由是"看到 Hacker News 上 Zig Language Reference 单页面就兴奋了"——C 级别控制力 + 性能,但没有 C 的精神负担。
Zig 的内存管理哲学是 显式优于隐式 。Zig 拒绝 C++ 的 ~Destructor 和 Rust 的 Drop 这种隐式 cleanup,强制要求用 defer 显式写出清理代码:
| 语言 | cleanup 机制 |
|---|---|
| Zig | defer、errdefer |
| C++ | ~Destructor、&&Move |
| Rust | Drop |
Bun 是 GC 写的 JavaScript 引擎和手写 C 库的胶水层 。Zig 的"显式 defer"在这种场景下非常容易出错:每次内存分配都要问四个问题——四次反问
1
这块内存在哪里被释放?
2
怎么保证只释放一次?
3
JavaScript 异常抛出了吗?
4
这个 GC 指针保守栈扫描器看得到吗?
Sumner 自承:JavaScript 是 GC 语言,JavaScriptCore(Safari 的引擎)和 V8 对异常处理和 GC 都有严格规则。 Zig 像 C 一样不管内存 ,让这两种范式混在一起写出来,是 Bun 稳定性问题的主要来源。
可以选的方案
01
风格指南 + 代码评审
TigerBeetle 的 TigerStyle 是代表,但风格指南的问题是如何强制执行
02
换 C++
能拿到构造函数/析构函数,但仍依赖风格指南 + ASAN
03
换 Rust
borrow checker 把内存错误变成编译器错误
「Homegrown smart pointers 比 Rust 差太多 ergonomics,没有 Rust 的任何保证。」
Sumner 在 2025 年尝试过给 Bun 写 Rust 风格的智能指针(SharedPtr),但他承认上面这一点。
03
THE TRANSPILE STRATEGY
重写不是"重写",是 transpile 风格移植
按传统软件工程经验, 重写是最糟糕的决定 。Bun 现在 535,496 行 Zig(不算注释),一个小型工程师团队完整重写需要整整一年,期间要冻结 bug fix、安全 fix、特性开发。最低风险的方案是 机械化的转译——把 Zig 代码一行一行翻译成 Rust,行为不变,跑同一套测试套件。
幸运的是,Bun 的测试套件是用 TypeScript 写的, 不依赖 runtime 的编程语言 。
两个关键决策
整体重写还是增量重写
Sumner 在 2021 年把 esbuild 从 Go 移植到 Zig 时用过"整体重写"路线,没有 LLM 辅助。增量重写会产生临时代码,希望未来被删除,短期到中期都很痛苦。所以 整体重写 。
保持架构还是利用 Rust 特性
保持架构。用 Rust 的 borrow checker,但不全面改造架构、不追求"更 idiomatic 的 Rust"。等 Bun v1.4 发布后再做。
04
CLAUDE, REWRITE BUN
Claude, rewrite Bun in Rust.
"一开始我也不信这件事能成。" Sumner 在 Anthropic 收购 Bun 之后,有了 内部预发布版 Claude Fable 5 。他问自己的问题是:花一周时间测试,如果模型能改写 Bun,就继续。
几天后, 测试套件的大量用例开始通过 。新写的 Rust 代码和原 Zig 代码的对应度让他改变判断——从"值得试一下"到"我要 merge 这个"。
但关键不是"Claude, rewrite Bun in Rust. Don't make any mistakes." 这种祈祷式 prompt。Sumner 实际上做了非常系统化的工作:
1
写一份 porting guide——把 Zig 的每个模式/类型映射到 Rust 的对应物
2
机械式地逐文件移植——.zig → .rs
3
修每个 crate 的编译错误
4
修子命令——bun test、bun build 等 CLI 工具先跑通
5
跑通整个测试套件——TypeScript 写的百万级断言
6
几次大重构和清理
50
个动态工作流
11
天不间断运行
他用 50 个动态 workflow (dynamic workflows),在 11 天 内不间断地跑 Claude Code。
工作流循环
PSEUDOCODE
let task; while ((task = todoList.pop())) { const result = task(); const feedback = await Promise.all([review(result), review(result)]); await apply(feedback, result); }
这本质上就是把"软件工程师的日常工作"——写代码、提 PR、收 review、改反馈——程序化成了一个可以并行跑的循环 。
05
ADVERSARIAL REVIEW
怎么 review 一个 +100 万行新增代码的 PR?
11 天 + 50 个 workflow + Claude 写代码——这些数据放在一起,最难的问题不是"模型写不写得出来",而是 "人怎么敢 merge 它" 。
Sumner 给出的答案是三件套:
语言无关的测试套件
百万级断言,TypeScript 写的,和 runtime 语言无关。这是 Bun 长期投资的红利。
对抗式 code review
让 Claude 在独立的 context window 里,假装代码是错的,穷尽一切可能的方式找 bug。
修流程而不是修代码
发现 bug 时,不去手改那一行代码,而是修生成这段代码的 workflow。这样下次生成的同类代码自动修复。
对抗式 review 的关键设计
1 个 implementer + 2 个以上 adversarial reviewer。Implementer 只管写代码,不管 review;Reviewer 只管找 bug,不管写代码。Implementer Claude 想让代码被接受("ship 偏好"),Reviewer Claude 想找代码的问题("质疑偏好")。Implementer 看不到 Reviewer 的输入,Reviewer 只看 diff。
Sumner 在 blog 里给了三个对抗式 review 实际抓住的 bug——全部能编译通过、全部看起来合理 ,但都是错的:
BUGS CAUGHT BEFORE MERGE
· bug 1 of 3 · the async close
在 async close 路径上 lifetime 错误
· bug 2 of 3
· bug 3 of 3——原 blog 里有完整 commit hash 和 reviewer 标注
每个被 review 抓住的 bug,commit message 都在 subject line 里标了 review attribution。
06
AFTER V1.4
Bun 的未来:v1.4 之后才是真正的 Rust 化
Bun v1.4 之前的 Rust 重写, 架构上完全保持 Bun 原样——只是把 Zig 改成了 Rust。性能指标、API 兼容性、模块系统、所有用户能感知的部分都不变。
Sumner 明确说:
「我们做的是那种看上去像是把 Zig 代码 transpile 成 Rust 的重写。我们会逐步重构以减少 unsafe 用量,并让它更接近 idiomatic Rust——但那是 Bun v1.4 之后的事。」
这意味着:
1
v1.4 之前的 Rust 代码里,unsafe 块可能比 idiomatic Rust 多
2
v1.4 之后会做几轮"清理",把不安全的 unsafe 包装成更 Rusty 的抽象
3
但用户不会感知到任何差异——这是一次纯底层重写
07
ECOSYSTEM IMPLICATIONS
对整个 JavaScript 生态意味着什么?
把这次重写放在更大的背景下看,有三层意义:
第一层 · 基础设施软件的 AI 重写从理论变成工程现实
Firefox 去年用 AI 辅助写过一个组件,但从未有过 整个 runtime 的 AI 重写并被接受合并。Bun 是第一个。
第二层 · 语言选择不再是一锤子买卖
Sumner 在原文里说:"直到最近,编程语言选择对 Bun 这种项目来说还是单向决定"。Claude Fable 5 改变了这个事实——未来你可以在不同语言间"切换"而不需要一年冻结期 。
第三层 · V8 / JavaScriptCore 团队需要重新思考 AI 战略
Bun 的成功重写会逼着所有 runtime 作者回答一个问题: 我们什么时候也用 AI 改写底层 ?
更深一层: Anthropic 收购 Bun 不到一年 ,用自家最强的预发布模型重写自家收购的 JavaScript runtime——这不是产品行为,这是 模型能力的范式证明 。Claude Fable 5 能用 11 天时间把 53 万行 Zig 改写成 Rust 并通过百万级测试,这是模型对长程、复杂、有状态工程任务的标志性胜利。
∞
EPILOGUE
写在最后
Bun 的 Rust 重写不是"AI 替代程序员"的故事——它恰恰相反。 是 Jarred Sumner 这个 Bun 的创造者 :
知道哪些 bug 必须修;知道 Bun 的测试套件在哪、怎么跑;知道哪些是真正的设计决策(整体重写、保持架构);知道怎么设计 prompt 和 workflow(50 个动态工作流);知道怎么 review 100 万行新代码(对抗式 review)。
Sumner 自己是 prompt engineer,是 workflow architect,是 adversarial review designer。Claude Fable 5 是执行者。
未来的基础设施工程师 不会只写代码——他们会 写会写代码的 AI 跑的 workflow 。
参考资料
· Jarred Sumner 原文:bun.com/blog/bun-in-rust
· Anthropic 收购 Bun 公告:anthropic.com(2025-12)
· Fuzzilli:github.com/googleprojectzero/fuzzilli
· TigerBeetle TigerStyle:tigerstyle.dev
· Bun 测试套件:github.com/oven-sh/bun/tree/main/test
END
如果你觉得今天这篇有收获,欢迎 点赞、在看、转发 三连,我们下篇见。