needhelp
← Back to blog

Bun का Rust रीराइट: 11 दिन, 6,778 कमिट, और असल में क्या बदला

by needhelp
Bun
Rust
Zig
JavaScript Runtime
LLM
Software Engineering

Bun की टीम ने मई 2026 में कुछ असामान्य शिप किया: उन्होंने रनटाइम की पूरी नेटिव कोर को एक Rust पोर्ट से बदल दिया, और वो भी 11 दिनों में।

ऐलान के ऊपर लिखी हुई बात टोन सेट कर देती है। Bun को दिसंबर 2025 में Anthropic ने खरीद लिया था। Bun के क्रिएटर Jarred Sumner ने काम का बड़ा हिस्सा Claude के प्री-रिलीज़ वर्शन — जिसे वो “Mythos-class model” कहते हैं, Fable 5 — से किया। ये कोई थॉट एक्सपेरिमेंट नहीं है। पहला Rust वर्शन, Bun v1.4.0, अभी canary में है।

कच्चे नंबर ये हैं:

  • 535,496 लाइन Zig (कमेंट्स को छोड़कर) की एक Rust कोडबेस बन गई
  • 3 मई से 14 मई के बीच 6,778 कमिट
  • 1,448 .zig फ़ाइलों को मशीनी तरीके से .rs में पोर्ट किया गया
  • API खर्च लगभग $165,000 (5.9B अनकैश्ड इनपुट टोकन, 690M आउटपुट टोकन)
  • पीक पर: 4 वर्कट्रीज़ में एक साथ 64 Claudes चल रहे थे

Rust रीराइट के बाद Bun का स्टार्टअप, Claude Code के नीचे चलते हुए

Bun हमेशा से एक Zig दाँव था

Bun शुरू हुआ था esbuild के JS/TS ट्रांसपाइलर को Go से Zig में लाइन-बाय-लाइन पोर्ट करके। Sumner ने 16 अप्रैल 2021 को Hacker News पर Zig की सिंगल-पेज लैंग्वेज रेफरेंस देखने के बाद अपनी पहली Zig लाइन लिखी। पहला वर्शन — ट्रांसपाइलर, मिनिफ़ायर, बंडलर, npm-कंपैटिबल पैकेज मैनेजर, Jest-जैसा टेस्ट रनर, Node.js API सरफेस — एक आदमी ने एक साल में, एक छोटे से Oakland अपार्टमेंट में, तब लिखा था जब LLM ऐसे काम के लायक नहीं थे।

वो दाँव चल गया। Bun के CLI की अब 22 मिलियन से ज़्यादा मंथली डाउनलोड्स हैं। Claude Code और OpenCode इसे अपना रनटाइम बनाते हैं। Vercel, Railway और DigitalOcean फर्स्ट-पार्टी सपोर्ट शिप करते हैं।

स्कोप ही दिक्कत भी था।

कर्ज़: GC मेमोरी के बगल में मैनुअल मेमोरी

JavaScript गारबेज-कलेक्टेड है। Bun के अंदर JavaScriptCore (Safari वाला इंजन) के साथ C/C++ लाइब्रेरीज़ का ढेर है: uWebSockets, BoringSSL, SQLite, lsquic। Zig, C की तरह, आपके लिए मेमोरी मैनेज नहीं करता। Bun का काम एक GC वाली लैंग्वेज और मैनुअली-मैनेज्ड नेटिव कोड के बीच में खड़े होने का है, और बगों में सबसे बुरे इसी बाउंड्री पर रहते थे।

ऐलान में v1.3.14 अकेले में उनहोंने जो फिक्स किए उनकी एक झलक लिस्ट है: node:zlib में एक heap-use-after-free, री-एंट्रेंट कॉलबैक्स से node:http2 में use-after-free, UDPSocket.sendMany में out-of-bounds राइट्स, हर tls.connect पर एक मेमोरी लीक, CSS पार्सर में एक double-free। लिस्ट आगे भी चलती है, और टेक्निकल है।

Sumner साफ़ कहते हैं कि ये Zig की गलती नहीं है। “We wouldn’t have gotten this far if not for Zig, and I’ll always be grateful.” (Zig के बिना हम इतना आगे नहीं पहुँचते, और मैं हमेशा शुक्रगुज़ार रहूँगा।) असल समस्या स्ट्रक्चरल है: GC बाउंड्री के पार लाइफटाइम्स को हैंडल करना किसी भी लैंग्वेज में मुश्किल है जो इसके लिए डिज़ाइन न की गई हो, और Zig का जवाब — हर कॉल साइट पर एक्सप्लिसिट defer — रेयरली-रीच्ड एरर पाथ्स में गलत होना आसान है।

उन्होंने C++ भी तोला। Bun का लगभग 20% पहले से ही C++ है, और और जोड़ने से कंस्ट्रक्टर्स और डिस्ट्रक्टर्स मिल जाते। पर फिर भी कोड रिव्यू के ज़रिए थोपे गए स्टाइल गाइड्स पर ही टिकना पड़ता, और मेमोरी करप्शन फिर भी होता।

Rust का पिच अलग है: सेफ Rust में, use-after-free, double-free, और “फ्री करना भूल गए” कंपाइलर एरर हैं। बोरो चेकर और Drop एक स्टाइल-गाइड प्रॉब्लम को टाइप-सिस्टम प्रॉब्लम में बदल देते हैं।

रणनीति: ट्रांसपाइल करो, रीडिज़ाइन नहीं

रीराइट्स की बदनामी है, और वजह सही है। 535K लाइनों का स्क्रैच से रीराइट फीचर्स और फिक्सेस को एक साल के लिए फ्रीज कर देता। Bun ने जो शेप चुनी वो एक मशीनी पोर्ट थी: वही आर्किटेक्चर, वही परफॉरमेंस टारगेट्स, वही फीचर्स, वही टेस्ट सूट — बस Rust में।

पूरी कोशिश को दो फैसलों ने ड्राइव किया:

  1. एक साथ सब, इनक्रीमेंटल नहीं। esbuild को Zig में पोर्ट करने का Sumner का अनुभव बताता था कि इनक्रीमेंटल रीराइट्स अस्थायी स्कैफोल्डिंग छोड़ जाती हैं जो मदद से ज़्यादा नुकसान करती हैं।
  2. इसे ट्रांसपाइल्ड दिखने दो। मकसद ऐसा Rust लिखना था जो अपनी Zig जैसी पढ़े, ताकि उसे idiomatic Rust की तरफ v1.4 शिप होने के बाद रीफैक्टर किया जा सके।

अहम बात, Bun का टेस्ट सूट TypeScript में लिखा है, तो उसे फर्क नहीं पड़ता कि रनटाइम किस लैंग्वेज में इम्प्लीमेंट है। इसी ने “सारे टेस्ट ग्रीन” को डन की डेफिनिशन बनने दिया।

तैयारी छोटी पर जानबूझकर की गई थी। कोड लिखने से पहले Sumner ने Claude के साथ ~3 घंटे Zig पैटर्न्स को Rust से मैप करने में बिताए; वो बातचीत PORTING.md बन गई (ये बाद में Hacker News पर चढ़ी)। एक दूसरे पास ने पूरी कोडबेस में हर struct फ़ील्ड की सही Rust लाइफटाइम्स का एनालिसिस किया और उन्हें LIFETIMES.tsv में सीरियलाइज़ किया। एक भी लाइन पोर्ट होने से पहले दोनों डॉक्युमेंट्स एडवर्सेरियल रिव्यू से गुज़रे।

जो वहीं रहा: JavaScriptCore और एम्बेडेड C/C++ लाइब्रेरीज़। रीराइट नेटिव ग्लू और Bun-स्पेसिफिक कोड की थी, JS इंजन की नहीं।

एक्ज़ीक्यूशन: 64 Claudes, 11 दिन

पोर्ट लगातार, 11 दिनों तक, Claude Code में लगभग 50 “डायनेमिक वर्कफ़्लोज़” के तौर पर चला। हर वर्कफ़्लो एक लूप था: टास्क लो, कोड बनाओ, रिव्यू करवाओ, फीडबैक लगाओ।

रिव्यू मॉडल दिलचस्प हिस्सा है। हर इम्प्लीमेंटर के लिए दो या ज़्यादा एडवर्सेरियल रिव्यूअर्स थे — अलग Claude सेशन्स जिन्हें बताया गया था कि कोड गलत है मानो और फेल होने का हर कारण ढूँढो। इम्प्लीमेंटर कभी रिव्यू नहीं करता; रिव्यूअर कभी इम्प्लीमेंट नहीं करता। ऐलान इसे इंसानी रिव्यू की नकल बताता है: ऑथर मर्ज करना चाहता है, तो चेक एक अलग पार्टी करती है।

कुछ मैकेनिक्स अलग से निकालने लायक हैं:

  • पहले ट्रायल रन। उन्होंने सारी 1,448 फ़ाइल्स कमिट करने से पहले 3 फ़ाइल्स पोर्ट कीं।
  • वर्कट्री शार्डिंग। शुरुआती रन में Claudes git stash और git reset के साथ एक-दूसरे को रौंद रहे थे। फिक्स: 4 वर्कट्रीज़, हर एक में 16 Claudes, और एक नियम कि टास्क के बीच में कभी git या cargo न चलाएँ।
  • कंपाइलर एरर्स को वर्क क्यू की तरह। cargo check ने ~16,000 एरर्स एक फ़ाइल में डंप किए, crate के हिसाब से ग्रुप की गईं, और 64 Claudes ने काट-छाँट की — 4 वर्कट्रीज़ में 16 fix/review/apply लूप।
  • साइक्लिकल डिपेंडेंसीज़। Zig असल में एक कंपाइलेशन यूनिट था; Rust को ~100 crates चाहिए थे। साइकल्स को untangle करने से उन 16,000 एरर्स में से ज़्यादातर सामने आए।
  • आइसोलेशन। जो स्ट्रेस टेस्ट्स TCP सॉकेट्स ख़त्म कर देते या ~10k प्रोसेसेस स्पॉन करते, वो systemd-run cgroups के नीचे चले। मशीन फिर भी डिस्क खत्म कर बैठी और कुछ बार क्रैश हुई।
timeline
    title Bun का 11-दिन का Zig → Rust रीराइट (मई 2026)
    2026-05-03 : पोर्ट ब्रांच खोली गई (PR #30412)
    2026-05-04 : पहला 100-फ़ाइल ड्राफ़ बैच
    2026-05-06 : ~16,000 कंपाइलर एरर, 64 Claudes
    2026-05-08 : पहली CI रन (972 फ़ेल फ़ाइलें)
    2026-05-09 : Linux x64 ग्रीन हो गया
    2026-05-11 : Windows ग्रीन (आख़िरी प्लैटफ़ॉर्म)
    2026-05-14 : सभी 6 प्लैटफ़ॉर्म ग्रीन, मर्ज्ड

नंबरों से: पीक पर एक मिनट में 1,300 लाइन कोड, सबसे व्यस्त घंटे में 695 कमिट (6 मई), सबसे व्यस्त एक मिनट में 58 कमिट। हर कमिट लैंड होने से पहले दो एडवर्सेरियल रिव्यूअर्स से रिव्यू हुई। आख़िरी डिफ़ +1,009,272 लाइन थी। कोई टेस्ट स्किप या डिलीट नहीं किया गया।

CI वहीं जगह थी जहाँ ये असली हुआ। पहली रन के दो दिन बाद, फेल टेस्ट फ़ाइल्स 972 से घटकर 23 रह गईं। डेढ़ दिन बाद Linux पूरी तरह ग्रीन हो गया। Windows आख़िरी 11 मई को खत्म हुआ; सभी छह प्लैटफ़ॉर्म्स बिल्ड #54202, 14 मई को ग्रीन थे।

Rust ने असल में क्या खरीदा

स्टेटेड गोल स्टेबिलिटी थी, और पोस्ट उसे पक्के नंबरों से बैक करती है।

बग्स। Bun v1.4.0 उन 128 बग्स को फिक्स करता है जो v1.3.14 में रिप्रोड्यूस होते हैं।

मेमोरी। Drop ने हर कॉल साइट वाले defer को रिप्लेस किया। पोस्ट की मिसाल: एक ही प्रोसेस में वही 60-मॉड्यूल प्रोजेक्ट 2,000 बार बंडल करना। v1.3.14 में हर बिल्ड ~3 MB हमेशा के लिए लीक करता है; v1.4.0 में मेमोरी लेवल ऑफ हो जाती है।

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

Zig में इसे फिक्स करने की एक पुरानी कोशिश कभी मर्ज नहीं हुई, Sumner लिखते हैं, क्योंकि Drop के बराबर के न होने से भरोसा करना मुश्किल था।

बाइनरी साइज़। अकेले Rust रीराइट ने 3.8 MB (Windows), 5.5 MB (macOS), 6.8 MB (Linux) काटे — ज़्यादातर एक्सेसिव Zig comptime हटाने से। आगे लिंकर वर्क (identical code folding, ICU डेटा ट्रिम करना) ने कुल श्रिंकेज को Linux और Windows पर ~20% तक ला दिया।

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

स्पीड। C/C++ और Rust के बीच क्रॉस-लैंग्वेज LTO कंपाइलर को लैंग्वेज बाउंड्री के पार इनलाइन करने देता है। Bun ने 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 ने अपना Compute पब्लिक बीटा 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.” (हमें मेमोरी लीक्स और एक कनेक्शन पूल मिला जो VM पॉज़ और रिज़्यूम होने के बाद रिकवर नहीं कर पाया। जब Rust रीराइट आई, हमने उसे उन्हीं फेल्योर मोड्स के खिलाफ टेस्ट किया। उसने उन्हें परफेक्ट हैंडल किया।)

Claude Code v2.1.181 (17 जून) और उसके बाद वाले Rust पोर्ट इस्तेमाल करते हैं। Linux पर स्टार्टअप 10% तेज़ है। यूज़र-विज़िबल बदलाव पर Sumner का वर्डिक्ट: “Boring is good.” (उबाऊ अच्छा है।)

जहाँ पोर्ट फिसला

535K लाइनों का वफ़ादार ट्रांसपाइल मुफ़्त नहीं है। पोस्ट 19 ज्ञात रिग्रेशन्स डॉक्युमेंट करती है, सभी फिक्स्ड। सबक देने वाले वो छोटे सेमांटिक गैप्स हैं जो लैंग्वेजेज के बीच हैं:

  • debug_assert! साइड इफ़ेक्ट्स। Zig का assert एक फंक्शन है, तो उसका आर्गुमेंट हर बिल्ड में चलता है। Rust का debug_assert! एक मैक्रो है जो रिलीज़ में मिट जाता है — एक insert_stale कॉल जो HMR स्टेट को साइलेंटली म्यूटेट करती थी, चलना बंद हो गई। (#30678)
  • ऑड-लेंथ स्लाइसेस। Zig का हेल्पर एक ट्रेलिंग ऑड बाइट को इग्नोर कर देता था; bytemuck::cast_slice उस पर पैनिक करता है। UTF-16 BOM प्लस एक ऑड बाइट काउंट पर Blob.text() क्रैश होने लगा। (#31188)
  • बाउंड्स चेक्स। Zig का ReleaseFast उन्हें स्ट्रिप करता है; Rust रखता है। एक प्लेसहोल्डर कॉन्स्टेंट ने फाइलनेम-इंटरनिंग सीलिंग को 8.4M से 270K कर दिया, और असल प्रोजेक्ट्स उससे टकराए। (#31503)
  • comptime फॉर्मैट स्ट्रिंग्स। Zig फॉर्मैट स्ट्रिंग्स कंपाइल टाइम पर एवैल्युएट करता है, तो कलर मार्कर्स आर्गुमेंट्स सब्स्टीट्यूट होने से पहले ही गायब हो जाते हैं। Rust में comptime नहीं है, तो मार्कर पार्सर OSC 8 हाइपरलिंक्स में एक लिटरल बैकस्लैश खा गया। (#30693)

ये वो बग्स हैं जो सिर्फ इसलिए सामने आते हैं क्योंकि दो लैंग्वेजेज एक जैसी दिखती हैं पर हैं नहीं।

इसका क्या मतलब है

LLM एंगल हटाओ और एक असल इंजीनियरिंग स्टोरी है: एक प्रोजेक्ट मैनुअल मेमोरी मैनेजमेंट जितना स्केल पर दे सकता था उसकी छत से टकराया, और उसने Rust के बोरो चेकर को टूल चुना ताकि बग्स की पूरी क्लास को नामुमकिन बनाया जा सके, न कि बस डिस्करेज किया गया।

LLM एंगल वो हिस्सा है जिस पर लोग बहस करेंगे। Sumner साफ़ कहते हैं कि इसमें फुल कोडबेस कॉन्टेक्स्ट वाले तीन इंजीनियर्स को करीब एक साल लगता, और वो इसे कभी करते ही नहीं — रियलिस्टिक विकल्प “कुछ न करो और बग्स फिक्स करते रहो” था। इसके बजाय, 64 Claudes की निगरानी करने वाले एक इंजीनियर ने इसे 11 दिनों में ~$165K में कर दिया।

Bun के Rust कोड का लगभग 4% unsafe ब्लॉक्स में है (~780,000 कुल लाइनों में से ~27,000 लाइनों पर ~13,000 unsafe कीवर्ड्स), और उन ब्लॉक्स का 78% सिर्फ एक लाइन का है। मर्ज के बाद से, उन्होंने 11 राउंड्स सिक्योरिटी रिव्यू चलाए हैं और हर पार्सर पर 24/7 कवरेज-गाइडेड फ़ज़िंग जोड़ी है — अभी तक 100 बिलियन एक्ज़ीक्यूशन्स, ~15 PRs।

मेंटेनेबिलिटी वाला सवाल वो है जिस पर मैं नज़र रखूँगा। Sumner कहते हैं Rust वैसी ही पढ़ती है जैसी Zig, और canMergeSymbols का साइड-बाय-साइड दिखाते हैं इसे साबित करने के लिए। दाँव ये है कि एक वफ़ादार पोर्ट पोर्ट-बाय-पोर्ट रिव्यूबल है, जिसने एक आदमी को मिलियन-लाइन डिफ़ पर साइन ऑफ करने दिया।

उनकी क्लोज़िंग लाइन वो है जो दिलचस्प बूढ़ी होगी: “One engineer can do a lot more today than a year ago.” (एक इंजीनियर आज एक साल पहले से कहीं ज़्यादा कर सकता है।)

References

Share this page