Tulis Ulang Bun ke Rust: 11 Hari, 6,778 Komit, dan Apa yang Sebenarnya Berubah
Tim Bun merilis sesuatu yang tidak biasa pada Mei 2026: mereka mengganti seluruh inti native runtime dengan port Rust, dan itu dilakukan dalam 11 hari.
Pengungkapan di awal pengumuman itu menetapkan nadanya. Bun diakuisisi oleh Anthropic pada Desember 2025. Jarred Sumner, pencipta Bun, menggunakan versi pra-rilis Claude — model “Mythos-class” yang mereka sebut Fable 5 — untuk sebagian besar pekerjaan. Ini bukan eksperimen pemikiran. Bun v1.4.0, versi Rust pertama, kini ada di canary.
Angka mentahnya:
- 535,496 baris Zig (tidak termasuk komentar) menjadi codebase Rust
- 6,778 komit antara 3 Mei dan 14 Mei
- 1,448 file
.zigdiporting secara mekanis ke.rs - Sekitar $165,000 untuk API (5.9B token input yang tidak di-cache, 690M token output)
- Puncak: 64 Claude berjalan serentak di 4 worktree

Bun selalu bertaruh pada Zig
Bun bermula sebagai port baris demi baris dari transpiler JS/TS esbuild, dari Go ke Zig. Sumner menulis baris Zig pertamanya pada 16 April 2021, setelah melihat referensi bahasa Zig satu halaman di Hacker News. Versi awal — transpiler, minifier, bundler, manajer paket yang kompatibel dengan npm, runner tes mirip Jest, surface API Node.js — ditulis sendiri oleh satu orang dalam satu tahun, di apartemen sempit di Oakland, sebelum LLM berguna untuk pekerjaan seperti ini.
Taruhan itu membuahkan hasil. CLI Bun kini melihat lebih dari 22 juta unduhan bulanan. Claude Code dan OpenCode menggunakannya sebagai runtime. Vercel, Railway, dan DigitalOcean menyediakan dukungan first-party.
Cakupannya juga masalahnya.
Utang: memori GC di sebelah memori manual
JavaScript di-garbage-collect. Bun menyematkan JavaScriptCore (mesin di Safari) plus tumpukan pustaka C/C++: uWebSockets, BoringSSL, SQLite, lsquic. Zig, seperti C, tidak mengelola memori untuk Anda. Tugas Bun adalah duduk di antara bahasa yang di-GC dan kode native yang dikelola manual, dan batas itulah tempat sebagian besar bug terburuknya berada.
Pengumuman itu mencantumkan contoh apa yang mereka perbaiki di v1.3.14 saja: heap-use-after-free di node:zlib, use-after-free di node:http2 dari callback re-entran, tulisan di luar batas di UDPSocket.sendMany, kebocoran memori per tls.connect, double-free di parser CSS. Daftarnya berlanjut, dan itu teknis.
Sumner tegas bahwa ini bukan salah Zig. “We wouldn’t have gotten this far if not for Zig, and I’ll always be grateful.” (Tanpa Zig kami tidak akan sampai sejauh ini, dan saya akan selalu bersyukur.) Masalahnya struktural: menangani lifetime di seberang batas GC sulit dalam bahasa apa pun yang tidak merancangnya, dan jawaban Zig — defer eksplisit di setiap call site — mudah disalahkan di jalur error yang jarang dijangkau.
Ia mempertimbangkan C++. Sekitar 20% Bun sudah dalam C++, dan memindahkan lebih banyak lagi akan memberi constructor dan destructor. Tapi tetap akan mengandalkan panduan gaya yang ditegakkan lewat code review, dan kerusakan memori tetap terjadi.
Pitches Rust berbeda: dalam safe Rust, use-after-free, double-free, dan “lupa membebaskan” adalah error compiler. Borrow checker dan Drop mengubah masalah panduan gaya menjadi masalah sistem tipe.
Strategi: transpile, jangan redesain
Rewrites punya reputasi buruk, dan ada alasannya. Rewrite dari nol untuk 535K baris akan membekukan fitur dan perbaikan selama setahun. Bentuk yang dipilih Bun adalah port mekanis: arsitektur sama, target performa sama, fitur sama, suite tes sama — hanya dalam Rust.
Dua keputusan menggerakkan seluruh upaya:
- Sekaligus, bukan bertahap. Pengalaman Sumner mem-porting esbuild ke Zig memberitahunya bahwa rewrite bertahap meninggalkan scaffolding sementara yang lebih merugikan daripada membantu.
- Buat terlihat seperti hasil transpile. Tujuannya adalah Rust yang terbaca seperti Zig asalnya, untuk di-refactor menuju Rust idiomatik setelah v1.4 rilis.
Yang penting, suite tes Bun ditulis dalam TypeScript, jadi ia tidak peduli bahasa apa yang digunakan untuk mengimplementasikan runtime. Itu memungkinkan mereka menjadikan “semua tes hijau” sebagai definisi selesai.
Persiapannya kecil tapi disengaja. Sebelum menulis kode, Sumner menghabiskan ~3 jam bersama Claude memetakan pola Zig ke Rust; percakapan itu menjadi PORTING.md (kemudian muncul di Hacker News). Pass kedua menganalisis lifetime Rust yang tepat untuk setiap field struct di seluruh codebase dan menyerialisasikannya ke LIFETIMES.tsv. Kedua dokumen menjalani review adversarial sebelum satu baris pun di-porting.
Yang tetap di tempatnya: JavaScriptCore dan pustaka C/C++ yang disematkan. Rewrite-nya adalah lem native dan kode spesifik-Bun, bukan mesin JS.
Eksekusi: 64 Claude, 11 hari
Port berjalan sebagai sekitar 50 “dynamic workflow” di Claude Code, terus-menerus, selama 11 hari. Setiap workflow adalah sebuah loop: ambil tugas, hasilkan kode, review, terapkan umpan balik.
Model review adalah bagian yang menarik. Untuk setiap implementer, ada dua atau lebih adversarial reviewer — sesi Claude terpisah yang disuruh menganggap kode itu salah dan mencari setiap alasan ia gagal. Implementer tidak pernah mereview; reviewer tidak pernah mengimplementasikan. Pengumuman membingkai ini sebagai cermin review manusia: penulis ingin merge, jadi pihak lain yang memeriksa.
Beberapa mekanisme layak ditarik keluar:
- Coba dulu. Mereka mem-porting 3 file sebelum berkomitmen pada semua 1,448.
- Worktree sharding. Run awal membuat Claude saling menginjak dengan
git stashdangit reset. Perbaikannya: 4 worktree, 16 Claude masing-masing, dengan aturan untuk tidak menjalankan git atau cargo di tengah tugas. - Error compiler sebagai antrean kerja.
cargo checkmembuang ~16,000 error ke file, dikelompokkan per crate, dan 64 Claude menggerogotinya — 16 loop fix/review/apply di 4 worktree. - Dependensi siklikal. Zig pada dasarnya satu unit kompilasi; Rust butuh ~100 crate. Memisahkan siklus mengungkap sebagian besar dari 16,000 error itu.
- Isolasi. Tes stres yang menghabiskan soket TCP atau memunculkan ~10k proses berjalan di bawah cgroup
systemd-run. Mesin tetap kehabisan disk dan crash beberapa kali.
timeline
title Tulis ulang Bun Zig → Rust 11 hari (Mei 2026)
2026-05-03 : Cabang port dibuka (PR #30412)
2026-05-04 : Batch draft 100 file pertama
2026-05-06 : ~16,000 error compiler, 64 Claude
2026-05-08 : CI run pertama (972 file gagal)
2026-05-09 : Linux x64 hijau
2026-05-11 : Windows hijau (platform terakhir)
2026-05-14 : Keenam platform hijau, di-merge
Berdasarkan angka: puncak 1,300 baris kode per menit, 695 komit dalam jam tersibuk (6 Mei), 58 komit dalam satu menit tersibuk. Setiap komit direview oleh dua adversarial reviewer sebelum masuk. Diff akhir adalah +1,009,272 baris. Tidak ada tes yang dilewati atau dihapus.
CI adalah tempat itu menjadi nyata. Dua hari setelah run pertama, file tes gagal turun dari 972 menjadi 23. Satu setengah hari kemudian Linux sepenuhnya hijau. Windows selesai terakhir pada 11 Mei; keenam platform hijau di build #54202, 14 Mei.
Apa yang sebenarnya dibeli Rust
Tujuan yang dinyatakan adalah stabilitas, dan posting tersebut mendukungnya dengan angka keras.
Bug. Bun v1.4.0 memperbaiki 128 bug yang direproduksi di v1.3.14.
Memori. Drop menggantikan defer per call site. Contoh posting: membundel proyek 60-modul yang sama 2,000 kali dalam satu proses. Di v1.3.14 setiap build bocor ~3 MB selamanya; di v1.4.0 memori mencapai plateau.
| Builds | v1.3.14 | v1.4.0 |
|---|---|---|
| 500 | 1,914 MB | 526 MB |
| 1,000 | 3,506 MB | 586 MB |
| 1,500 | 5,097 MB | 608 MB |
| 2,000 | 6,745 MB | 609 MB |
Percobaan sebelumnya untuk memperbaiki ini di Zig tidak pernah di-merge, tulis Sumner, karena tidak adanya padanan Drop membuat sulit untuk yakin.
Ukuran biner. Rewrite Rust sendiri memotong 3.8 MB (Windows), 5.5 MB (macOS), 6.8 MB (Linux) — sebagian besar dari membuang comptime Zig yang berlebihan. Pekerjaan linker lebih lanjut (identical code folding, memangkas data ICU) membawa penyusutan total ke ~20% di Linux dan Windows.
| Version | Platform | Size |
|---|---|---|
| v1.4.0 | Windows | 76 MB |
| v1.3.14 | Windows | 94 MB |
| v1.4.0 | Linux | 70 MB |
| v1.3.14 | Linux | 88 MB |
Kecepatan. LTO lintas-bahasa antara C/C++ dan Rust memungkinkan compiler melakukan inline melintasi batas bahasa. Bun mengukur keuntungan 2–5%:
Bun.serve: 169.6k → 177.7k req/s (+4.8%)express: 64.5k → 66.6k (+3.2%)next build: 13.62s → 13.03s (+4.5%)tsc -b --force: 0.94s → 0.89s (+4.7%)
Prisma memindahkan public beta Compute-nya ke atas rewrite Rust. Alexey Orlenko: “We ran into memory leaks and a connection pool that couldn’t recover after a VM was paused and resumed. When the Rust rewrite appeared, we tested it against the same failure modes. It handled them perfectly.” (Kami mengalami kebocoran memori dan connection pool yang tidak bisa pulih setelah VM dijeda dan dilanjutkan. Ketika rewrite Rust muncul, kami mengujinya terhadap mode kegagalan yang sama. Ia menanganinya dengan sempurna.)
Claude Code v2.1.181 (17 Juni) dan versi setelahnya menggunakan port Rust. Startup 10% lebih cepat di Linux. Verdik Sumner soal perubahan yang terlihat pengguna: “Boring is good.” (Membosankan itu baik.)
Di mana port itu selip
Transpile setia 535K baris tidak gratis. Posting mendokumentasikan 19 regresi yang diketahui, semua diperbaiki. Yang mengajarkan adalah celah semantik kecil antarbahasa:
- Efek samping
debug_assert!.assertZig adalah sebuah fungsi, jadi argumennya berjalan di setiap build.debug_assert!Rust adalah makro yang dihapus di release — sebuah panggilaninsert_staleyang memutasi state HMR secara diam-diam berhenti berjalan. (#30678) - Slice dengan panjang ganjil. Helper Zig mengabaikan satu trailing odd byte;
bytemuck::cast_slicepanik karenanya.Blob.text()pada UTF-16 BOM plus hitungan byte ganjil mulai crash. (#31188) - Pemeriksaan batas.
ReleaseFastZig memangkasnya; Rust menyimpannya. Sebuah konstanta placeholder menurunkan plafon filename-interning dari 8.4M ke 270K, dan proyek nyata menabrakanya. (#31503) - String format
comptime. Zig mengevaluasi string format saat compile time, jadi penanda warna sudah hilang sebelum argumen disubstitusi. Rust tidak punyacomptime, maka parser penanda memakan backslash literal di hyperlink OSC 8. (#30693)
Ini bug yang hanya muncul karena dua bahasa terlihat identik tapi tidak.
Apa artinya ini
Lepaskan sudut LLM dan ada cerita rekayasa nyata: sebuah proyek mencapai langit-langit batas apa yang bisa diberikan manajemen memori manual pada skala, dan memilih borrow checker Rust sebagai alat untuk membuat seluruh kelas bug mustahil daripada sekadar tidak disarankan.
Sudut LLM adalah bagian yang akan diperdebatkan orang. Sumner terus terang bahwa ini akan memakan waktu sekitar setahun dengan tiga engineer yang memiliki konteks codebase penuh, dan mereka tidak akan pernah melakukannya — alternatif realistisnya adalah “tidak melakukan apa-apa dan terus memperbaiki bug.” Sebaliknya, satu engineer yang mengawasi 64 Claude melakukannya dalam 11 hari dengan ~$165K.
Sekitar 4% kode Rust Bun ada di blok unsafe (~13,000 kata kunci unsafe di seluruh ~27,000 baris dari total ~780,000), dan 78% blok tersebut hanya satu baris. Sejak merge, mereka menjalankan 11 putaran review keamanan dan menambahkan fuzzing berpandu-cakupan 24/7 di setiap parser — 100 miliar eksekusi sejauh ini, ~15 PR.
Pertanyaan pemeliharaan adalah yang akan saya awasi. Sumner mengatakan Rust terbaca seperti Zig, dan menunjukkan side-by-side canMergeSymbols untuk membuktikan poin itu. Taruhannya adalah port setia dapat direview port-demi-port, yang memungkinkan satu orang menyetujui diff sejuta baris.
Baris penutupnya adalah yang akan menjadi menarik seiring waktu: “One engineer can do a lot more today than a year ago.” (Satu engineer bisa melakukan jauh lebih banyak hari ini daripada setahun lalu.)