11天、64个Claude、16.5万美元:深入解析Bun从Zig到Rust的世纪迁移
前言:当最激进的语言实验拥抱最安全的系统语言
2026年7月8日,JavaScript运行时Bun的创始人Jarred Sumner在GitHub和X上同时发布了一条重磅公告:经过约6天的全力冲刺,64个Claude实例并行运行,Bun的核心运行时已从Zig完全重写为Rust——超过96万行代码,测试套件通过率99.8%,二进制文件体积缩小3-8MB,整体性能提升2-5%,修复了128个以上的bug。
这条消息在Hacker News上迅速引爆,评论区里有人惊叹"这是AI编程的里程碑",也有人质疑"6天真的能做到吗",更多的人则在讨论一个更深层的问题:当一个以极致手工控制著称的系统软件,选择拥抱Rust这门以内存安全为核心的语言,背后究竟经历了怎样的权衡?这个决定会对整个前端工具链生态产生什么影响?
这篇文章,我们不聊新闻,从一个写过Zig也写过Rust的工程师视角,把这次迁移的前因后果、技术细节、工程启示一次性讲透。
一、背景:Bun是什么,为什么Zig不是终点
要理解这次迁移的深层意义,先得弄清楚Bun的定位和Zig在其中的角色。
1.1 Bun:不止是一个运行时
Bun不仅仅是一个JavaScript运行时,它是一个全栈JavaScript工具链——同时包含了:
- 运行时(Bun Runtime):直接执行JS/TS,兼容Node.js API
- 打包器(Bundler):替代Webpack/Vite的部分功能
- 包管理器(Bun Install):替代npm/yarn/pnpm
- 测试运行器(Bun Test):内置测试框架
- 内置数据库驱动:支持SQLite、PostgreSQL
这种"All-in-One"的设计哲学,让Bun在某些场景下可以一个可执行文件搞定所有事。对比Node.js生态需要node + npm + webpack + jest等多个工具链组件,Bun的极简主义非常诱人。
1.2 Zig的吸引力与它的代价
Bun最初选择Zig,并非拍脑袋决定。Zig的核心设计哲学是"C的现代化替代"——无隐藏控制流、无垃圾回收、完全手动的内存管理、零成本抽象。这几点对于追求极致性能的JS运行时来说,简直是量身定做。
看一下Zig的几个核心特性:
// Zig的错误处理:显式、无隐藏开销
const result = try someFunction();
if (result) |value| {
// 处理成功情况
} else |err| {
// 处理错误情况
}
// Zig的内存管理:完全手动,给你所有控制权
const allocator = std.heap.page_allocator;
const memory = try allocator.alloc(u8, 1024 * 1024);
defer allocator.free(memory);
// Zig的 comptime:编译时计算,无runtime开销
fn fibonacci(comptime n: u32) u32 {
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
对于需要精密控制每字节内存去向的底层系统编程来说,Zig的这些特性是巨大的优势。但问题也恰恰出在这里。
当项目规模从几千行增长到几十万行时,手动内存管理的脆弱性开始暴露。 Bun的贡献者和用户频繁报告各种内存错误——use-after-free、data race、内存泄漏——这些问题在Zig中很难根除,因为Zig虽然强制显式错误处理,但在内存安全方面并不比C++强多少。
Jarred Sumner本人在多个场合提到过:"Zig的内存bug让我花费了大量时间,每次修复一个另一个就冒出来,根本原因是语言本身没有机制来防止这类错误。"
1.3 Anthropic收购:一个关键转折点
2025年12月,Anthropic收购了Bun,并基于Bun构建其核心状态机基础设施。这一收购案不仅仅是资本运作——它直接促成了Rust迁移的决定:
- Anthropic有强烈的动机让Bun更稳定:Bun成为Anthropic基础设施的一部分,任何内存崩溃都会直接影响其核心业务
- 有足够的资金支持迁移成本:16.5万美元的API token费用,在Anthropic收购背景下不值一提
- Claude Code成为迁移主力工具:Anthropic自己的代码代理工具,自然成为首选
二、迁移真相:6天到底发生了什么?
2.1 时间线:比标题党更复杂的故事
网上流传最广的说法是"11天完成",但仔细看时间线会发现更复杂的图景:
| 时间 | 事件 |
|---|---|
| 2026年5月11日 | Sumner在X宣布将启动Rust重写 |
| 2026年5月12日-17日 | 核心迁移期(6天),96万行代码 |
| 2026年5月17日 | Rust版本通过测试套件99.8%,被合并入主分支 |
| 2026年5月24日 | 正式发布Bun v1.4.0(Canary) |
| 2026年7月8日 | Sumner正式发布博客详细阐述迁移过程 |
| 2026年7月24日 | Claude Code v2.1.181确认集成Rust版Bun |
所以实际的密集开发期是6天,不是11天。11天可能包含了后续的bug修复、测试完善和发布准备工作。
2.2 迁移规模:数字背后的工程量
几个关键数字需要深入解读:
96万行代码:这是从Zig到Rust的代码行数。但这个数字要理性看待——AI迁移产生的代码往往包含更多的注释、更冗长的模式匹配、以及为了"保险"而写的额外检查代码。原始的Zig代码可能更精简但也更难懂。实际代码量减少约20%,二进制文件缩小3-8MB。
99.8%测试通过率:剩下0.2%的失败测试主要集中在两个领域:
- 平台特定行为(Windows/ARM上的边界case)
- 极端并发场景(race condition相关)
128个bug修复:这些修复大多是结构性的,而非简单的语法翻译——很多是Zig代码中隐藏多年的内存问题,在Rust编译器面前无所遁形。
6,755个commit:平均每天超过1,000个commit。这说明迁移是高度自动化的,AI在流水线上持续产出代码。
三、核心技术挑战:Zig到Rust不只是翻译
3.1 语言哲学的根本差异
Zig和Rust表面上看都是"系统级、无GC、性能优先"的语言,但它们的设计哲学有根本性差异:
Zig哲学: "给你所有工具,你自己负责"
- 裸指针可以随意使用(@ptrCast)
- 内存管理完全手动(allocator模式)
- 错误处理显式但不强制(可忽略!_ = try xxx)
- 编译时计算强大(comptime)
- 无泛型(用anytype和类型推断)
Rust哲学: "给你安全,你必须遵循规则"
- 裸指针只能在unsafe块中使用
- 内存通过所有权系统自动管理
- 错误处理通过Result类型强制传播
- 泛型系统丰富(trait、generic types)
- 编译时安全检查无处不在
最核心的差异在于:Rust用编译器规则来保证内存安全,而Zig把内存安全的责任完全交给了程序员。
3.2 迁移的具体挑战与解法
3.2.1 内存管理模式的转换
Zig的内存管理模式是全手动的,每个函数都需要传入allocator:
// Zig:内存分配是显式的、局部的
fn processData(allocator: std.mem.Allocator, input: []const u8) ![]u8 {
const result = try allocator.alloc(u8, input.len);
@memcpy(result, input);
return result;
}
Rust的等价实现需要使用Box、Vec、Arc等智能指针,由Rust的所有权系统自动管理生命周期:
// Rust:内存通过所有权系统自动管理
fn process_data(input: &[u8]) -> Vec<u8> {
let mut result = Vec::with_capacity(input.len());
result.extend_from_slice(input);
result
}
但Bun作为JS运行时,面临的挑战远比这个例子复杂——它需要同时与JavaScriptCore的GC堆和原生手动管理的内存打交道:
// Bun中的双内存世界挑战
use std::sync::Arc;
// JavaScript值在JS堆上,由JSC的GC管理
let js_value: JSValue = ...;
// 原生内存由Rust的allocators管理
let native_buffer: Vec<u8> = Vec::with_capacity(4096);
// 在JSC和Rust之间传递数据需要精确定义生命周期
unsafe fn pass_to_js(ctx: &mut JSContext, value: JSValueRef) -> JSValue {
// 这里是unsafe的边界——需要手动保证所有权的正确转移
JSValue::from_ref(ctx, value)
}
3.2.2 错误处理范式的转换
Zig的错误处理是显式的,但可以"忽略"(用_ = try xxx或直接try传播):
// Zig: 错误可以传播也可以忽略
const file = openFile("test.txt") catch |err| {
std.debug.print("Error: {}\n", .{err});
return; // 吞掉错误
};
Rust要求Result必须被处理,要么通过?传播,要么显式处理:
// Rust: Result无处可逃
let file = File::open("test.txt").map_err(|e| {
eprintln!("Error: {}", e);
})?;
但在实际迁移中发现,Zig代码中有大量catch unreachable的模式——这在Zig中意味着"这里理论上不会出错",但在Rust中需要用unwrap()或expect()来表达同样的语义:
// Zig: catch unreachable = 相信我这里不会出错
const value = maybeNull orelse unreachable;
// Rust: 同样需要明确表达
let value = maybe_null.expect("this should never be None");
3.2.3 并发模型的对齐
Zig的并发(特别是其suspend/resume机制)与Rust的async/await完全不同。Bun的event loop大量使用了Zig的低级并发原语:
// Zig: 基于纤程的并发
fn asyncTask() void {
suspend {
// 恢复时执行这里
resume @frame();
}
// 异步逻辑
}
迁移到Rust后,Bun团队选择了不使用async Rust,而是维持一个类似Tokio但更轻量的自定义executor,直接管理绿色线程:
// Bun的Rust版本:自定义轻量级executor
use std::sync::atomic::{AtomicU64, Ordering};
pub struct BunEventLoop {
tasks: Slab<Task>,
next_id: AtomicU64,
// 不使用async/await,而是手动管理Task状态
}
impl BunEventLoop {
pub fn spawn<F>(&mut self, future: F) -> TaskId
where F: Future<Output = ()> + 'static
{
let id = TaskId(self.next_id.fetch_add(1, Ordering::Relaxed));
self.tasks.insert(Task {
future: unsafe { NonNull::new_unchecked(Box::into_raw(Box::new(future))) },
state: TaskState::Ready,
id,
});
id
}
}
这是一个非常务实的决定——async Rust虽然安全,但在高性能网络场景下,其调度开销可能成为瓶颈。Bun的选择是保持zero-cost的调度,同时用Rust的类型系统来保证其他方面的安全。
3.3 unsafe代码:从73个到13,000个
有一个数据特别值得注意:CSDN的报道指出,原始的Rust UV项目(Anthropic的Python包管理器)只有73个unsafe调用,但迁移后的Bun Rust版本却有超过13,000个。
这说明什么?
Bun的架构本身就是一个"unsafe密集型"系统。 它需要:
- 直接操作JavaScriptCore引擎的内部API
- 与操作系统的底层接口(epoll/kqueue、文件系统调用)
- 实现高性能的内存池(arena allocator)
- 绕过JS GC和Rust RAII之间的阻抗不匹配
这些场景在Rust中就是需要unsafe的,没有办法回避。13,000个unsafe不是代码质量问题的标志,而是Bun架构本质的体现。关键在于:这些unsafe都被限制在明确定义的模块边界内,外层API仍然是类型安全的。
四、AI辅助迁移:工程可控性分析
4.1 Claude Code在这次迁移中做了什么
从公开信息推断,Claude Code在这次迁移中承担了以下角色:
- 模式化代码翻译:将Zig的数据结构、错误处理模式、内存操作模式一一对应到Rust等价实现
- 批量类型签名生成:Rust的类型系统远比Zig丰富,AI负责填充大量泛型约束
- 测试驱动修复:基于现有测试套件,AI自动修复编译失败和测试不通过的情况
- 文档和注释生成:AI自动添加注释,解释某些复杂逻辑的意图
但AI也做不了的事:
- 架构决策:哪些模块合并、哪些抽象需要引入,需要人工判断
- 性能调优:热点路径的优化,需要profiler数据和人工经验
- unsafe边界的精确定义:在哪里突破Rust的安全边界,需要对两个语言都有深度理解
4.2 工程可控性评分(来自博客园技术分析文章的评分参考)
基于这次迁移的公开数据,我给出一个更细化的评分:
| 维度 | 评分(1-10) | 说明 |
|---|---|---|
| 代码翻译准确性 | 8/10 | 大规模机械化翻译准确率高,但边缘case处理参差不齐 |
| 测试覆盖保持 | 9/10 | 99.8%通过率是最好的证明 |
| 性能保持 | 7.5/10 | 整体提升2-5%,但部分极端场景有轻微回归 |
| 架构完整性 | 6/10 | 迁移后unsafe激增说明架构打磨仍在进行 |
| 长期可维护性 | 9/10 | Rust生态和人才储备远优于Zig |
| AI辅助效率 | 9/10 | 6天完成预计1年的工作,效率革命 |
总结:这次迁移是AI辅助大型系统重写的成功案例,但成功的前提是Bun拥有业界领先的测试套件作为"规格文档",以及Anthropic充足的资本和人才支撑。普通团队照搬这个模式,风险依然不小。
五、性能与稳定性:Rust版Bun真的更好吗?
5.1 性能数据
根据Bun官方发布的benchmark和第三方独立测试结果:
| 场景 | Zig版Bun | Rust版Bun | 变化 |
|---|---|---|---|
| Linux冷启动速度 | 基准 | 快约10% | ↑10% |
| HTTP服务器吞吐量 | 基准 | 持平~+2% | ↑2% |
| 文件 I/O 操作 | 基准 | 持平 | → |
| TypeScript编译 | 基准 | 快约5% | ↑5% |
| SQLite查询 | 基准 | 持平 | → |
| macOS启动速度 | 基准 | 持平~+3% | ↑3% |
总体评价:Rust版在所有平台上均未出现性能退化,部分场景有小幅提升。
但这个"小幅提升"来之不易。Rust编译器对unsafe代码的优化能力比Zig的更成熟,但Rust的抽象层(trait、泛型)如果使用不当也会引入额外开销。Bun团队花了不少时间在profiler上优化热点路径。
5.2 稳定性:128个bug和长期收益
128个bug修复是这次迁移最实在的收益。这些bug包括:
- 多个内存泄漏(长期积累)
- 数据竞争(concurrent access race)
- use-after-free(在FFI边界上)
- 多个flaky测试(时序相关的测试不稳定)
Rust的所有权系统和生命周期检查在编译时就抓住了这些问题——这些问题在Zig中只能在运行时被偶然发现或者通过大量的内存安全工具来检测。
六、开发者视角:这次迁移教会我们什么
6.1 AI辅助重写的适用条件
Bun的案例告诉我们,AI辅助大型代码库重写是可行的,但需要满足以下条件:
✅ 强测试覆盖:AI翻译需要"规格文档"来验证正确性
✅ 明确的语言对应关系:Zig→Rust有大量模式可对应,降低了理解成本
✅ 充足的资源:16.5万美元不是小数目,64个并行实例需要工程基础设施
✅ 可接受的短期不稳定:6天内完成的代码,必然存在需要后续打磨的角落
✅ 明确的动机:Anthropic收购给了团队最强的动机和资源
❌ 不适合:没有测试套件的项目
❌ 不适合:没有充足预算的团队
❌ 不适合:架构设计本身存在根本性问题的代码库
6.2 Zig与Rust的选型思考
这次迁移给我们的另一个启示是:Zig和Rust不是竞争关系,而是互补的。
- Zig适合:小团队、需要极致手工控制、生态依赖少、生命周期明确的工具型软件
- Rust适合:大规模团队、需要长期维护、内存安全优先、复杂并发模型的基础设施
如果你现在从零开始写一个高性能工具链,选Rust的ROI通常更高。如果你已经在用Zig且运行良好,没有必要因为这次迁移而焦虑。
6.3 展望:AI编程的未来
Jarred Sumner说过一句话:"未来开源项目可能禁止人类直接提交代码。"这句话或许夸张,但它指向了一个趋势:AI正在从根本上改变大型软件工程的节奏。
过去,一个数十万行代码的系统重写,需要数十名工程师、数年时间、巨额预算。今天,借助AI,同等规模的迁移可以在数周内完成,成本从数百万美元降低到十几万美元。但随之而来的问题是:我们是否在用代码正确性换取工程速度?
Bun的答案是:在有强测试套件保护的前提下,可以。这次迁移没有发生灾难性的bug,是测试套件救了场。没有测试的代码重写,无论AI还是人类来做,都是赌博。
七、总结:一次改变认知的工程实践
Bun从Zig到Rust的迁移,是2026年最值得记录的工程事件之一。它证明了:
- AI辅助大型代码库迁移已经进入实用阶段,但强测试覆盖是必要前提
- Rust的内存安全保证在生产级软件中具有不可替代的价值,特别是在被Anthropic这样的大厂采纳后
- unsafe代码的量级不是问题,边界清晰才是问题,Bun在13,000个unsafe中保持了良好的模块边界
- 性能与安全不是零和博弈,Rust版本在安全提升的同时,性能并未退化
更重要的是,这次迁移给我们提供了一个审视AI编程能力边界的真实案例。它不是PPT里的demo,不是营销号里的传说——而是GitHub上真实存在的6,755个commit、96万行新增代码、一个完整测试套件的99.8%通过率。
如果你正在考虑用AI辅助你的团队进行技术栈迁移,Bun的案例是迄今为止最完整的参考。但记住Sumner那句话背后的潜台词:测试套件是AI迁移的生命线,没有它,AI就是在黑暗中跳舞。
参考来源:
- Jarred Sumner官方博客公告(2026年7月8日)
- IT之家:Bun Rust重构报道(2026年7月11日)
- 博客园:工程可控性分析(2026年7月15日)
- CSDN:百万行代码迁移深度解析(2026年7月17日)
- OSCHINA:Bun官方社区公告(2026年7月9日)
- Simon Willison博客:Claude Code集成Rust版Bun测试(2026年7月19日)