- Bun का Rust पुनर्लेखन Zig में बने मौजूदा आर्किटेक्चर और data structures को बनाए रखते हुए उसे अधिक mainstream tech stack में ले जाने वाले फ़ैसले के अधिक क़रीब है
- पुनर्लेखन PR का आकार 6,755 commits था और 8 मई को खुलने के बाद 14 मई को merge हो गया, जिससे production-grade runtime बदलाव की review depth पर सवाल बने रहते हैं
- tests का pass होना केवल ज्ञात paths और व्यवहार को सत्यापित करता है; error paths, concurrency, और अत्यधिक memory conditions जैसी global invariants तक की गारंटी देना कठिन है
- मुख्य बात Zig की विफलता नहीं, बल्कि तेज़ release को महत्व देने वाली Bun टीम की संस्कृति और manual memory management की लागत के बीच का संरचनात्मक असंगति है
- असली bet Zig बनाम Rust नहीं, बल्कि यह है कि AI द्वारा जनरेट किया गया और पर्याप्त रूप से review न किया गया code लंबे समय तक maintain किया जा सकता है या नहीं
Zig ने बनाई Bun की नींव
- Bun के Rust पुनर्लेखन PR को देखने से पहले, Bun के आज की स्थिति तक पहुँचने में Zig की भूमिका बड़ी थी
- Jarred ने Zig को “कूल” होने की वजह से नहीं चुना था, बल्कि इसलिए कि garbage collection के बिना high-performance JS runtime को एक छोटी टीम तेज़ी से prototype कर सकती थी
- Zig का low friction, direct memory manipulation, और simple C interoperability, Bun के शुरुआती performance और छोटे team size को संभव बनाते थे
- Jarred के इस कथन के अनुसार कि “architecture नहीं बदलेगा, और data structures भी नहीं बदलेंगे”, Rust पुनर्लेखन Zig में बने skeleton को आगे बढ़ाने वाली संरचना के ज़्यादा क़रीब है
- Zig से नींव बनाना, product launch करना, funding जुटाना, फिर company के अधिग्रहण और बढ़ने के बाद अधिक mainstream tech stack में जाना एक सामान्य business decision माना जा सकता है
- लेकिन इसे Zig की अपनी अनुपयुक्तता के रूप में पेश करना कठिन है
6 दिनों में merge हुए बड़े पुनर्लेखन का जोखिम
- पुनर्लेखन PR ने 6,755 commits, branch name
claude/phase-a-port, 8 मई को open और 14 मई को merge होने का रिकॉर्ड छोड़ा
- मुख्य समस्या यह है कि production-grade JS runtime का पूरा पुनर्लेखन सिर्फ 6 दिनों में merge हो गया
- software engineering का मूल सिद्धांत है: “जिस code को आप समझते नहीं, उसे production में नहीं चलाना चाहिए”
- यह सिद्धांत इसलिए नहीं है कि code में ज़रूर bug होगा, बल्कि इसलिए कि जब bug आए तो कहाँ से देखना शुरू करना है, यह भी पता न हो; यही maintainability की baseline बनती है
- PR के reviewers की सूची में
coderabbitai[bot], claude[bot] थे, और एकमात्र human reviewer alii की स्थिति “Awaiting requested review” थी
- Claude ने लिखा और Claude ने review किया — यह closed loop तर्क की दृष्टि से असंभव तो नहीं, लेकिन व्यवहार में इसका मतलब यही है कि पूरे codebase को किसी इंसान ने वास्तव में अंत तक पढ़ा नहीं
tests pass होने से क्या सुनिश्चित नहीं होता
- भले ही सभी platforms पर test suite pass हो जाए, यह केवल ज्ञात व्यवहार और ज्ञात paths की शुद्धता को सत्यापित करता है
- test suite के लिए निम्न क्षेत्रों की पर्याप्त गारंटी देना कठिन है
- क्या error paths सही ढंग से handle हो रहे हैं
- stress स्थितियों की boundary conditions पर व्यवहार कैसा है
- concurrency की स्थिति में state consistency बनी रहती है या नहीं
- अत्यधिक परिस्थितियों में memory model इरादे के अनुसार काम करता है या नहीं
- Jarred ने भी यह स्वीकार किया बताया गया है कि JS boundary में दोबारा प्रवेश करते समय memory issues को Rust compiler संभाल नहीं सकता और वहाँ अब भी इंसानों पर निर्भर रहना पड़ता है
- समस्या यह है कि जिस हिस्से में इंसानी निर्भरता चाहिए, उसी हिस्से को इंसानों ने review नहीं किया
- AI द्वारा code translation अधिकतर इस तरह की local semantic equivalence के क़रीब होती है जिसमें हर function को उसके मूल के समान, अलग-थलग स्तर पर काम करने लायक बनाया जाता है
- functions के बीच की global invariants, और वे design constraints जो tests में नहीं लिखे गए बल्कि मूल लेखक के दिमाग़ में ही थे, उन्हें केवल AI translation से सुनिश्चित करना कठिन है
- ऐसे constraints अभी tests में दिखाई न दें, लेकिन 6 महीने बाद किसी खास production load पर समझाना कठिन crash के रूप में सामने आ सकते हैं
- यह सिर्फ Claude की समस्या नहीं है; पर्याप्त review के बिना translation करने वाले सभी tools और human programmers पर भी यही बात लागू होती है
- 6,755 commits के पैमाने पर यह जोखिम बहुत बढ़ जाता है
अधिग्रहण के बाद बदला जोखिम उठाने वाला
- शुरुआती Bun, Jarred का ख़ुद पर लगाया गया दांव था, और Zig का उपयोग, तेज़ iteration, तथा technical debt को स्वीकार करना, ख़ुद जोखिम उठाने वाली startup logic के रूप में देखा जा सकता है
- अब जबकि Bun का किसी बड़े enterprise द्वारा अधिग्रहण हो चुका है और इसका user base वास्तविक production systems में इसका उपयोग करता है, पुनर्लेखन का जोखिम उठाने वाला Jarred नहीं बल्कि production में Bun चलाने वाले engineers और उनके पीछे के users हो गए हैं
- Jarred का कहना है कि यह version अभी canary में है, और official release से पहले optimization और cleanup का काम बाकी है
- canary एक सुरक्षा-रेखा है, लेकिन human review का विकल्प नहीं
- optimization और cleanup code quality के मुद्दे हैं; वे इस प्रश्न का समाधान नहीं करते कि maintainers ने code को समझा भी है या नहीं
- ऐसा codebase जिसे टीम में किसी ने भी पूरी तरह नहीं पढ़ा, उसमें चाहे tests व्यापक हों या canary अवधि लंबी, maintainers के लिए internal state एक black box ही बनी रहती है
- यह समस्या आगे चलकर गंभीर bugs को debug करने के समय वास्तविक पीड़ा के रूप में सामने आ सकती है
Zig समस्या के निदान में त्रुटि
- Jarred द्वारा पहले दिया गया कारण यह था कि Zig codebase में use-after-free, double-free, और error paths में memory leaks बहुत थे
- यह diagnosis अपने आप में सही हो सकता है, लेकिन यहाँ से “Zig काम नहीं करता” वाला निष्कर्ष निकालना कठिन है
- अधिक सटीक diagnosis यह है कि तेज़ iteration को प्राथमिकता देने वाले commercial project में manual memory management की cognitive cost टीम के budget से अधिक हो गई
- इसे Zig की bug नहीं, बल्कि Zig के design goals और Bun के business model के बीच की संरचनात्मक असंगति के रूप में देखा जा सकता है
- Zig के लक्षित users वे system programmers हैं जो जानते हैं कि वे क्या कर रहे हैं, और अंतिम control के लिए उसकी लागत चुकाने को तैयार हैं
- TigerBeetle ने Zig में लगभग memory bugs रहित database लिखा, क्योंकि टीम की संस्कृति और project का स्वभाव Zig की philosophy से मेल खाता था
- Bun टीम की संस्कृति तेज़ iteration, तेज़ release, और तेज़ bug fixes के अधिक क़रीब है, और यह Zig द्वारा माँगी जाने वाली सख़्त memory discipline के साथ मूलभूत तनाव में है
- “हमारी टीम इस tool के साथ बार-बार गलती करती है” को “यह tool अनुपयुक्त है” के रूप में पढ़ना attribution error के क़रीब है
- यह उपमा दी गई है कि अगर हथौड़ा फिट नहीं बैठा, तो इसका मतलब यह नहीं कि गलती हथौड़े की ही है
अल्पकालिक संभावना और दीर्घकालिक जोखिम
- अल्पकाल में यह काफ़ी संभव है कि पुनर्लेखित version अधिकांशतः ठीक निकले
- मुख्य paths tests से cover हो जाते हैं, canary चरण में स्पष्ट समस्याएँ सामने आ जाती हैं, और Rust compiler की guarantees memory bugs की एक श्रेणी को हटा देती हैं
- सतह पर सब कुछ सामान्य लग सकता है
- लेकिन दीर्घकाल में 6,755 commits जिन्हें किसी इंसान ने पूरी तरह नहीं पढ़ा एक संरचनात्मक जोखिम बने रहते हैं
- 6 महीने बाद यदि कोई अजीब concurrency bug सामने आता है, या किसी खास load पर boundary condition असामान्य व्यवहार पैदा करती है, तो debugging engineer को ऐसे system का सामना करना पड़ेगा जिसे किसी ने वास्तव में कभी समझा ही नहीं
- “ऐसा system जिसे समझा नहीं गया” का मतलब यह नहीं कि उसमें bugs नहीं हैं, बल्कि यह कि जब bug आए तो क्यों आया, यह किसी को नहीं पता होगा
- इस पुनर्लेखन का असली तकनीकी bet Zig बनाम Rust नहीं, बल्कि यह है कि AI द्वारा जनरेट और बिना review वाला code production environment में लंबे समय तक maintain किया जा सकता है या नहीं
- यह सवाल “सारे tests pass हो रहे हैं” से अधिक जटिल है, और “Rust की memory safety” से भी अधिक गहरा मुद्दा है
- निष्कर्ष को इस उपमा में समेटा गया है: “नींव Zig ने बनाई, इमारत Claude ने खड़ी की, और human reviewer अभी रास्ते में है”
- यह इमारत कितने समय तक रहने लायक रहेगी, यह इस पर निर्भर करता है कि पहली leak आने पर कोई उसका blueprint पढ़ सकता है या नहीं
1 टिप्पणियां
Lobste.rs की राय
“Bun को Rust में फिर से लिखें” पर बात करने से पहले यह कहना चाहिए कि Bun आज जहाँ पहुँचा है, वह Zig की बदौलत है
Bun के निर्माता Jarred भी ऐसा ही कह रहे हैं. उनका कहना है कि Zig ने Bun को संभव बनाया, और Oakland के एक बदबूदार कमरे में एक साल तक अकेले कोड किए गए प्रोजेक्ट का JavaScript ecosystem के सबसे व्यापक रूप से इस्तेमाल होने वाले टूल्स में से एक बन जाना काफी हद तक Zig की देन है
साथ ही यह भी कहा गया कि Zig एक शानदार भाषा है और Bun की सफलता उस पर बहुत कुछ उधार है, लेकिन Ghostty या Tigerbeetle जैसे दूसरे प्रोजेक्ट्स को Bun जैसी stability समस्याएँ नहीं झेलनी पड़ीं
आम तौर पर database में stability की चुनौतियाँ language runtime की तुलना में कहीं बड़ी होती हैं
इस लेख से बहुत ज़्यादा LLM द्वारा लिखे जाने की गंध आती है
इसलिए यह एहसास machine translation के निशान भी हो सकता है
अगर Zig का target user “ऐसा systems programmer है जो जानता है कि वह क्या कर रहा है, और ultimate control के लिए कीमत चुकाने को तैयार है”, तो यह Rust और Swift के बाद आई भाषाओं के संदर्भ में फिर से उभरे C/C++-style overconfidence जैसा लगता है
अगर Jarred ने बदलाव की वजह यह बताई कि “Zig codebase में use-after-free, double-free, और error path में memory leak बहुत ज़्यादा थे”, तो यह इस सवाल पर एक data point बनता है कि क्या सिर्फ LLM से memory-safety bugs ढूँढ़वाकर memory-unsafe भाषा को व्यवहारिक रूप से सुरक्षित बनाया जा सकता है
यहाँ तक कि LLM कंपनियों ने भी वह रास्ता नहीं चुना
“कोड Claude ने लिखा, कोड Claude ने review किया, इसलिए यह बंद चक्र तार्किक रूप से असंभव तो नहीं, लेकिन इसका मतलब है कि किसी इंसान ने इस पूरे codebase को वास्तव में कभी पढ़ा ही नहीं” — यह बात साफ़ तौर पर सही नहीं लगती
अगर इंसानों द्वारा लिखे गए Zig codebase का Rust में यांत्रिक अनुवाद किया गया है, तो मूल कोड समझने वाला व्यक्ति नए कोड को भी समझ सकता है। यह कोई APL में अनुवाद तो नहीं है; दोनों ही C syntax परंपरा की procedural भाषाएँ हैं
आगे चलकर अगर LLM को बिना निगरानी चलाया जाए तो कोड धीरे-धीरे मानवीय समझ से दूर जा सकता है — यह बात खुली हुई है, लेकिन इस समय का codebase अभी भी उतना समझने योग्य लगता है जितना दस लाख पंक्तियों वाले JavaScript runtime और single-binary all-purpose tool से उम्मीद की जा सकती है
“AI सिर्फ function-level local semantic equivalence मिलाता है, functions के बीच के global invariants नहीं समझता” — यह वाक्य LLM के पक्ष में भी और उसके ख़िलाफ़ भी अजीब लगता है
LLM इतने deterministic नहीं हैं कि यह guarantee दे सकें कि हर function मूल की तरह ही काम करेगा। ऐसी guarantee के लिए
c2rustजैसे tools चाहिए। LLM ऐसा कोड अनुवाद कर सकते हैं जो मूल जैसा दिखे, लेकिन((abc & 45) << 3) == 360को((abc & 45) << 30) == 360में बदलने से रोकने का काम compiler, test suite, और शायद LLM-based code review की probabilistic detection ही कर सकती हैउल्टा, अगर
c2rustकी तरह हर function की समानता guarantee करने वाला और LLM की तरह comments व structure भी बचाए रखने वाला translator हो, तो वह एकदम परफ़ेक्ट translator होगा और दस लाख पंक्तियों वाले codebase को भी अपने-आप port कर सकता है। Compiler को भी ऐसी ही एक विशेष स्थिति के रूप में देखा जा सकता है, और Clang भले bug-free न हो, लेकिन इतना क़रीब है कि लोग उस पर भरोसा करते हैं। अगर LLM, Clang-स्तर की reliability के साथ Zig या C++ को Rust में translate कर सकता, तो Chrome इस महीने के अंत तक pure Rust हो चुका होताऔर functions के बीच invariants को encode करना तो type system का मूल काम ही है। Bun को Rust में फिर से लिखने की एक वजह यह भी है कि Rust type system जटिल invariants को बेहतर ढंग से व्यक्त कर सकता है। ऐसा नहीं है कि Anthropic ने सब कुछ assembly में compile करके source code जला दिया हो
Bun को Rust port से बहुत पहले से vibe coding के साथ लिखा जाता रहा है। इसने AI को काफ़ी जल्दी अपना लिया था, और Anthropic के acquisition के बाद तो लगभग हर commit bot द्वारा लिखा गया है। Jarred ने ट्वीट भी किया था कि उसने वीकेंड में AI से features लिखवाकर कई features जोड़ दिए
HTML Parsers in Portland Python HTML parser की कई ports का विश्लेषण करता है और दिखाता है कि एक मुख्य algorithm हर port में बहुत अलग तरह से implement हुआ। जबकि हर case में mechanical port संभव था, व्यवहार में ऐसा नहीं हुआ
बेशक वह इस साल की शुरुआत का मामला था और process भी अलग था, लेकिन port के बाद Bun codebase में जो कुछ टुकड़े मैंने देखे हैं, वे भी ऐसी ही समस्याओं से जूझते लगते हैं
लेकिन “LLM इतने deterministic नहीं हैं कि यह guarantee दे सकें कि हर function मूल जैसा ही व्यवहार करता है” — यह अंततः इस निष्कर्ष तक ले जाता है कि किसी इंसान ने वास्तव में पूरे codebase को नहीं पढ़ा
“सभी tests pass हो रहे हैं” का एक उदाहरण: https://github.com/oven-sh/bun/…
दूसरे forums में भी कई लोगों को वही commit link करते देखा है; लगता है कहीं वह लिंक देखकर लोगों को लगा कि यह उनकी अपेक्षा से मेल खाता है, लेकिन उन्होंने यह नहीं जाँचा कि उसका वास्तविक संबंध है भी या नहीं। मुझे लगता है कि हमें अपने लिए इससे ऊँचा मानदंड रखना चाहिए
पहला commit: “await process exit / JSON-parse-retry instead of fixed sleeps”
revert: “test: revert proc.exited change in spawn.test.ts, keep isDebug iteration count”
“जिस कोड को आप समझते नहीं, उसे production में नहीं चलाना चाहिए” — इस सिद्धांत के बारे में मैं इन दिनों बहुत सोच रहा हूँ
मेरा career काफ़ी आगे बढ़ चुका है, लेकिन मैंने जानबूझकर management में नहीं गया, और programming career भी धीरे-धीरे stack के निचले हिस्से की तरफ़ गया है। वजह यह है कि मुझे असली program को गहराई से समझना पसंद है। Features ship करना और users की ज़िंदगी बेहतर बनाना बेहद महत्वपूर्ण है, लेकिन programming का एक बड़ा आंतरिक reward यह एहसास भी है कि आप वास्तविक systems के बारे में सच बातें सीख रहे हैं
मेरे जैसे व्यक्ति के लिए यह लगभग एक axiom जैसा लगता है कि इंसान को program की हर पंक्ति समझनी चाहिए। लेकिन org chart में मेरा manager उस program के लिए ज़िम्मेदार है जिसे मैं maintain करता हूँ। वह एक शानदार manager है और micromanage नहीं करता, इसलिए टीम जो software ship करती है उसकी हर पंक्ति को वह समझे — यह स्वाभाविक नहीं है। सच कहूँ तो पता नहीं उसने code लगभग पढ़ा भी है या नहीं। तो क्या वह इस सिद्धांत का उल्लंघन कर रहा है
मैं सोच रहा हूँ कि “वह कोड जो मेरे अधीन काम करने वाले ने लिखा और मैं नहीं समझता” और “वह कोड जो मेरी AI ने लिखा और मैं नहीं समझता” — इन दोनों के बीच कोई सार्थक अंतर है या नहीं
पहला मुझे स्वीकार्य लगता है, लेकिन दूसरा असहज करता है। क्या फ़र्क बस इतना है कि उस कोड के लिए ज़िम्मेदारी लेने वाला इंसान मौजूद है? या बस कोई ऐसा है जिस पर दोष डाला जा सके? यह मेरे भीतर की इस मज़बूत नैतिक भावना को सही ठहराने के लिए काफ़ी है या नहीं, यह अभी तय नहीं है
मुझे चिंता है कि यह तीव्र भावना अच्छी engineering के लिए ज़रूरी चीज़ न होकर सिर्फ़ निजी सौंदर्यबोध के क़रीब हो। लोगों की अपनी पसंद हो सकती है, लेकिन अगर बात बस इतनी ही है, तो शायद मुझे मान लेना चाहिए कि इस काम का यह पहलू आगे चलकर कम सुखद होगा। आखिरकार मैं management की तरफ़ धकेला जाऊँगा, बस फ़र्क इतना होगा कि मेरे अधीन काम करने वाले bots होंगे
कहा जाता है कि “Zig ने छोटी टीम को garbage collector और heavy runtime के बिना high-performance JS runtime जल्दी prototype करने दिया”, लेकिन दूसरे बड़े runtimes Node और Deno भी वही काम कर रहे हैं
दोनों ही garbage-collector-रहित भाषाओं C++ और Rust में JS engine को wrap करते हैं। V8 या JSC खुद वास्तव में garbage collector के साथ ship होते हैं या नहीं, यह मुझे पक्का नहीं, लेकिन वह मुख्य बिंदु नहीं है
पूरा Bun repository किसी dystopia जैसा लगता है। Bots आपस में बात करते हुए बेतुके PR बना रहे हैं
उदाहरण: https://github.com/oven-sh/bun/issues/30766
इसे “पूरा” मान लेने की रफ़्तार काफ़ी चौंकाने वाली है, लेकिन यह वैसा चलती ट्रेन का हादसा नहीं लगता जैसा लेख बिना ठोस सबूत के दिखाता है
“छह महीने बाद कोई अजीब concurrency bug सामने आएगा, और किसी खास load पर कोई boundary condition गड़बड़ी पैदा करेगी, तब debugging करने वाला engineer ऐसे system से जूझ रहा होगा जिसे किसी ने भी वास्तव में कभी समझा ही नहीं” — यह महज़ अटकल है, इसके समर्थन में कोई तथ्य नहीं दिया गया
Language porting LLM के लिए उपयुक्त क्षेत्र है, और आधार code को पहले से बहुत से इंसान समझते थे। एक साधारण language port अचानक diagnosability को अपूरणीय रूप से क्यों नष्ट कर देगा, यह मुझे समझ नहीं आता