2 पॉइंट द्वारा GN⁺ 3 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Zig से शुरू हुआ Bun अब हर महीने 2.2 करोड़ से अधिक डाउनलोड होने वाला runtime बन चुका है, लेकिन GC-आधारित JavaScript engine और manual memory management के मेल से बार-बार आई stability समस्याएँ Rust में बदलाव की वजह बनीं
  • 535,496 लाइनों के Zig कोड को किसी इंसान द्वारा 1 साल में स्थानांतरित करने के बजाय, Claude Code के लगभग 50 dynamic workflows और अधिकतम 64 Claude instances को 11 दिनों तक parallel में चलाया गया
  • पोर्टिंग को PORTING.md, LIFETIMES.tsv, 1 implementer और कम-से-कम 2 adversarial reviewers, तथा मौजूदा TypeScript test suite से सत्यापित किया गया, और 6-platform CI में 100% पास हुआ
  • Rust में बदलाव के बाद Bun v1.4.0 ने v1.3.14 में पुन: उत्पन्न होने वाले 128 bugs ठीक किए, सभी instrumentable memory leaks को सुधारा, और Linux·Windows binary size को लगभग 20% घटाया
  • Bun v1.3.14 आख़िरी Zig version है और v1.4.0 पहला Rust version है, जिसे canary में उपलब्ध कराया गया है; टीम borrow checker, Miri, LeakSanitizer, और 24/7 coverage-based fuzzing को stability सुधारने के टूल के रूप में इस्तेमाल कर रही है

Zig से शुरू हुआ Bun और stability समस्याएँ

  • Bun की शुरुआत esbuild के JavaScript·TypeScript transpiler को Go से Zig में line-by-line port करने वाले प्रोजेक्ट के रूप में हुई
  • पहला Zig कोड 16 अप्रैल 2021 को लिखा गया था, और Zig का low-level control तथा performance-oriented design, Bun के शुरुआती implementation को संभव बनाता था
  • शुरुआती Bun को एक व्यक्ति ने 1 साल तक Zig में लिखा, और इसका दायरा बहुत व्यापक था
    • JavaScript, TypeScript, CSS transpiler·minifier·bundler
    • npm-compatible package manager
    • Jest-जैसा test runner
    • Node.js·TypeScript-compatible module resolution
    • HTTP/1.1·WebSocket client
    • fs, net, tls आदि Node.js API implementation
  • मौजूदा Bun CLI हर महीने 2.2 करोड़ से अधिक बार डाउनलोड होता है, Claude Code और OpenCode इसे runtime के रूप में इस्तेमाल करते हैं, और Vercel, Railway, DigitalOcean आदि 1st-party support प्रदान करते हैं

बार-बार आने वाले memory stability bugs

  • Bun v1.3.14 में ठीक किए गए bug samples में use-after-free, double-free, memory leak, out-of-bounds access, race condition शामिल थे
    • node:zlib में async .write() के दौरान .reset() कॉल करने से होने वाला heap-use-after-free
    • node:http2 में re-entrant JS callback द्वारा hashmap rehash ट्रिगर होने से internal stream pointer invalidate हो जाने वाला use-after-free
    • UDPSocket.send() और sendMany() में valueOf() या toString() callback के कारण ArrayBuffer detach हो जाने की समस्या
    • Buffer#copy, Buffer#fill में argument coercion के दौरान ArrayBuffer detach या resize होने से crash और out-of-bounds read
    • crypto.scrypt, tlsSocket.setSession(), fs.watch() से जुड़ी memory leaks
    • CSS parser में vendor prefix और multi-layer background handling के दौरान double-free
    • BroadcastChannel या MessagePort पर concurrent access के दौरान MessageEvent race condition crash
  • पहले से भी stability मज़बूत करने के लिए कई उपाय इस्तेमाल किए जा रहे थे
    • Zig compiler में Address Sanitizer support patch किया गया और हर commit पर ASAN test suite चलाया गया
    • Windows के लिए Zig safety-checked ReleaseSafe builds वितरित किए गए
    • Fuzzilli के साथ Bun runtime API पर 24/7 fuzzing की गई
    • end-to-end memory leak tests की बड़ी संख्या चलाई गई
  • यह रुख नहीं था कि समस्या Zig खुद है; बल्कि GC values और manually managed memory को साथ में संभालने की ज़रूरत stability समस्याओं का मुख्य स्रोत थी

Rust क्यों चुना गया

  • JavaScript एक GC language है और JavaScriptCore व V8 जैसे engines exception handling और GC पर सख्त नियम रखते हैं
  • Zig, C की तरह, memory को अपने-आप manage नहीं करता; इसमें constructor·destructor नहीं होते और cleanup ज़्यादातर हर call site पर defer के साथ स्पष्ट रूप से लिखना पड़ता है
  • Bun में GC values और manually managed values की lifetime को सही ढंग से संभालना stability समस्याओं का बड़ा स्रोत था
    • यह देखना पड़ता था कि allocated bytes कहाँ free हो रहे हैं
    • यह सुनिश्चित करना पड़ता था कि free केवल एक बार हो
    • JavaScript exception handling को सही तरह जाँचना पड़ता था
    • यह जाँचना पड़ता था कि GC pointers conservative stack scanner को दिख रहे हैं या नहीं
  • Zig का cleanup तरीका explicit defer, errdefer है, C++ destructor और move का उपयोग करता है, और Rust Drop का उपयोग करता है
  • Bun के मौजूदा Zig कोड में arena lifetime, reference counting, और बेहद सावधानी से की गई review का मिश्रण था
  • style guide और code review से ownership rules लागू किए जा सकते हैं, लेकिन Rust के safe code में use-after-free, double-free, और error path में छूटा हुआ free compiler error बन जाता है
  • Bun के लगभग 20% कोड C++ में हैं और इसमें कई C/C++ libraries embedded हैं
    • JavaScriptCore
    • uWebSockets and usockets
    • lshpack और lsquic
    • BoringSSL
    • SQLite
  • C++ भी एक विकल्प हो सकता था, लेकिन तब भी style guide और code review पर निर्भर रहना पड़ता, और ASAN होने के बावजूद memory corruption और leaks हो सकते थे

rewrite strategy: एक बार में, mechanical तरीके से

  • मौजूदा Bun Zig कोड, comments हटाकर, 535,496 lines का था, और पारंपरिक rewrite को छोटे engineering team के लिए लगभग 1 साल का काम माना गया
  • bug fixes, security fixes, और feature development को 1 साल तक रोका नहीं जा सकता था, इसलिए user behavior changes को न्यूनतम रखने वाला mechanical porting सबसे कम जोखिम वाला तरीका चुना गया
  • Bun का test suite TypeScript में लिखा गया था, इसलिए वह runtime implementation language पर निर्भर नहीं था
  • incremental rewrite को अल्पकाल और मध्यम अवधि में कष्टदायक माना गया, क्योंकि उसमें temporary code बनाना पड़ता और बाद में हटने की उम्मीद करनी पड़ती; इसलिए पूरा बदलाव एक ही बार में किया गया
  • Rust कोड को इस तरह लिखा गया कि वह Zig कोड के transpile किए गए रूप जैसा दिखे, और Bun v1.4 के बाद धीरे-धीरे unsafe कम करते हुए idiomatic Rust में refactor करने की दिशा चुनी गई

Claude Code dynamic workflow

  • Rust rewrite के लिए Claude Code में लगभग 50 dynamic workflows 11 दिनों तक लगातार चलाए गए
  • workflows में porting guide लिखने से लेकर file conversion, compiler errors ठीक करना, subcommand restore करना, पूरा test pass कराना, और बड़े पैमाने के cleanup तक सब शामिल था
    • Zig patterns और types को Rust patterns और types से map करने वाली porting guide बनाना
    • PORTING.md और LIFETIMES.tsv के अनुसार सभी .zig files को .rs files में mechanically port करना
    • crate-वार compiler errors ठीक करना
    • bun test, bun build जैसे subcommands का behavior restore करना
    • पूरा test suite pass कराना
    • बड़े पैमाने पर refactoring और cleanup
  • अधिकांश समय एक इंसान workflow output पढ़ता रहा, समस्याओं और bugs की जाँच करता रहा, और Claude loop को सुधारने के लिए prompts समायोजित करता रहा
  • तैयारी के तौर पर Claude के साथ लगभग 3 घंटे तक Zig codebase के patterns को Rust में map करने के तरीकों पर चर्चा हुई, और उसका नतीजा PORTING.md में serialize किया गया
  • manual memory management code में Rust lifetimes जोड़ने के लिए सभी struct fields की lifetime का विश्लेषण करने वाला workflow चलाया गया
    • complex lifetime वाले fields ढूँढे गए
    • lifetime suggestions दिए गए
    • 2 adversarial review agents ने समीक्षा की
    • feedback को शामिल करके LIFETIMES.tsv में सहेजा गया

प्रतिकूल समीक्षा पद्धति

  • हर implementation Claude के लिए अलग context window में एक प्रतिकूल reviewer Claude रखा गया, और reviewer को सिर्फ diff देकर यह मानकर bug ढूंढने को कहा गया कि code गलत है
  • बुनियादी संरचना में 1 implementer, 2 या उससे अधिक प्रतिकूल reviewer, और 1 fixer शामिल था
  • reviewer ने जो bug वास्तव में पकड़े, वे सभी compile तो हो गए थे लेकिन व्यवहार में समस्या पैदा कर रहे थे
    • uv_close asynchronous है, लेकिन Box<uv::Pipe> match arm के अंत में drop हो जाता था, जिससे libuv freed memory को पकड़े रहता था और use-after-free तथा double-free होता था
    • नकारात्मक non-integer file time पर trunc() इस्तेमाल करने से negative nsec बनता था, जिससे timespec error होती थी
    • unwrap_or arguments को eager evaluate करता है, इसलिए color-mix() percentage omission case में panic होने वाली त्रुटि थी
  • मानव review की तरह ही author और reviewer context अलग रखे गए, ताकि implementer के merge चाहने से पैदा हो सकने वाले पक्षपात को कम किया जा सके

बड़े पैमाने का porting execution और parallelization

  • कुल 1,448 .zig फ़ाइलों को स्थानांतरित करने से पहले पहले 3 फ़ाइलों के साथ प्रक्रिया को validate किया गया
    • 1 implementer ने .rs फ़ाइल लिखी
    • 2 reviewer ने जाँचा कि व्यवहार .zig के अनुरूप है और PORTING.md, LIFETIMES.tsv का पालन करता है
    • 1 fixer ने सुझाव लागू किए
  • पूरे फ़ाइल porting के शुरुआती चरण में कई Claude ने git stash, git stash pop, git reset HEAD --hard चलाए और वे आपस में टकरा गए
  • बाद में workflow में ऐसे नियम जोड़े गए जिनमें git stash, git reset, किसी खास फ़ाइल commit के अलावा git commands, और cargo जैसे धीमे commands पर रोक लगाई गई
  • अंत में 4 workflow shard और 4 worktree इस्तेमाल किए गए, और हर shard में 16 Claude फ़ाइलें commit और push करते थे
  • parallelization और पहले से की गई तैयारी की बदौलत peak पर Claude लगभग 1,300 lines of code प्रति मिनट लिख रहा था
  • port branch में merge को छोड़कर commits की संख्या 6,502 थी, peak hour में 695 commits हुए, और अंतिम landed diff +1,009,272 lines था
  • EC2 instance की default IOPS बढ़ाई नहीं गई थी, इसलिए एक धीमा grep भी disk read/write को कई मिनट तक रोक देता था

compile errors और crate separation

  • सारा code लिखे जाने के बाद Claude workflow ने compiler errors को ठीक किया
  • Zig codebase वस्तुतः एक compilation unit था, जबकि Rust code को तेज compile के लिए लगभग 100 crate में बाँटने की योजना थी
  • सबसे कठिन error category circular dependency थी
    • Rust rewrite से ठीक पहले किया गया crate separation PR अपने आप में पर्याप्त नहीं था
    • एक अलग workflow ने classify और record किया कि circular dependency वाले code को कहाँ रखा जाना चाहिए
    • दूसरे workflow ने संबंधित refactoring किया
  • circular dependency हल होने के बाद लगभग 16,000 compiler errors सामने आए
  • इन errors को crate के हिसाब से parallel में संभाला गया
    • हर crate में cargo check चलाया गया
    • output को फ़ाइल के हिसाब से समूहित करके सहेजा गया
    • उस crate की compile errors को ठीक किया गया
    • 2 प्रतिकूल reviewer ने बदलावों की समीक्षा की
    • 1 fixer ने सुधार लागू किए
  • Claude ने “सभी crate को compile होने लायक बनाओ” का अर्थ function stub बनाना समझ लिया, जिससे एक false start हुआ
  • जब लंबे explanatory comments से workaround को सही ठहराने का पैटर्न दिखा, तो एक review rule जोड़ा गया: “अगर paragraph-लंबाई comment चाहिए, तो code गलत है और code को ही ठीक करना चाहिए”

test pass होने तक की प्रक्रिया

  • cargo check pass होने के बाद linking errors, startup के तुरंत बाद panic, bun --version, और bun test <file> execution को क्रम से ठीक किया गया
  • CLI subcommand के हिसाब से failing stacktrace को फ़ाइलों में सहेजा गया, और implementer-reviewer-fixer loop वाले workflow से उन्हें सुधारा गया
  • test file workflow में लगभग 100 random test files को 4 worktree में shard किया गया, और हर failure के stacktrace और error को सहेजकर ठीक किया गया
  • test suite में memory leak tests और integration tests थे जो debug build में timeout हो सकते थे
    • next dev चलाकर hot module reloading द्वारा 100 बदलाव detect करने वाला test
    • TCP socket की अधिकतम संख्या समाप्त कर देने वाला stress test
    • gigabyte स्तर की disk read/write test
    • लगभग 10,000 processes spawn करने वाला test
  • isolation के लिए systemd-run और cgroups से memory और CPU usage सीमित की गई और pid namespace अलग किया गया
  • इसके बावजूद machine कई बार disk space खत्म होने से crash हुई
  • पहली CI run के दो दिन बाद failing test files की संख्या 972 से घटकर 23 रह गई, और उसके डेढ़ दिन बाद Linux पूरी तरह green हो गया
  • अंततः 6 platforms पर CI के पूरे tests pass हुए
    • macOS x64
    • macOS arm64
    • Linux x64
    • Linux arm64
    • Windows x64
    • Windows arm64
  • 100% test pass होने के बाद मनुष्यों ने हाथ से पुष्टि की कि tests वास्तव में चले थे और skip नहीं किए गए थे, फिर merge किया गया
  • main में merge के समय यह कोई versioned release नहीं था; release करने लायक भरोसा अभी नहीं था, लेकिन rewrite पर पूरी तरह ध्यान देने लायक भरोसा मिल चुका था

test scale और cost

  • 11 दिनों में, May 3 से May 14 merge तक 6,778 commits बनाए गए
  • tests को न हटाया गया, न skip किया गया
  • platform-वार test scale इस प्रकार थी
    • Debian 13 x64: expect() 1,386,826 बार, 60,624 tests, 4,174 files
    • macOS 14 arm64: expect() 1,259,953 बार, 58,850 tests, 4,175 files
    • Windows 2019 x64: expect() 1,007,544 बार, 57,337 tests, 4,173 files
  • pre-merge काम में 5.9 billion uncached input tokens, 690 million output tokens, और 72 billion cached input token read इस्तेमाल हुए
  • API pricing के आधार पर लागत लगभग 165,000 डॉलर थी
  • आकलन यह था कि अगर मनुष्य सीधे करते, तो पूरे codebase context वाले 3 engineers को लगभग 1 साल लगता
  • इस्तेमाल किया गया model pre-release Claude Fable 5 था, और इसमें यह disclosure शामिल था कि Bun को December 2025 में Anthropic ने अधिग्रहित किया था

security review, fuzzing, और unsafe की स्थिति

  • Rust port merge होने के बाद Claude Code Security के साथ 11 rounds का security review पूरा किया गया और findings को संभाला गया
  • Bun के सभी parser के लिए 24/7 coverage-based fuzzing जोड़ी गई
    • JavaScript
    • TypeScript
    • JSX
    • CSS
    • JSON5
    • JSONC
    • TOML
    • YAML
    • Markdown
    • INI
    • Bun Shell scripts
    • semver ranges
    • .patch files
    • CSS colors
  • fuzzer पाए गए bugs को Claude को भेजता है ताकि वह reproduction और fix सहित PR जमा करे, और मनुष्य PR की review करते हैं
  • अब तक parser execution 100 billion बार हो चुका है और इससे लगभग 15 PR बने हैं
  • लेखन के समय Rust code का लगभग 4% unsafe block के भीतर था
    • लगभग 13,000 unsafe keywords
    • लगभग 27,000 lines / कुल लगभग 780,000 lines
    • unsafe block का 78% एक-पंक्ति का था, और वह C++ से आए pointers या C library calls से जुड़ा था
  • उनका कहना था कि JavaScriptCore जैसी C/C++ libraries का उपयोग जारी रहने के कारण, यह संख्या शुद्ध Rust project की तुलना में हमेशा अधिक रहेगी

Rust में बदलाव के बाद मिले regression

  • Rust rewrite एक बड़ा बदलाव था, इसलिए 19 ज्ञात regression बने, और सभी को ठीक कर दिया गया
  • ज़्यादातर समस्याएँ ऐसे code से आईं जिनका syntax दोनों भाषाओं में मिलता-जुलता है, लेकिन semantics अलग हैं
  • debug_assert! के अंदर side effect

    • Zig का assert एक function है, इसलिए उसके arguments हर build में execute होते हैं
    • Rust का debug_assert! एक macro है, इसलिए release build में पूरा expression हटा दिया जाता है
    • insert_stale call release build में गायब हो गया, जिससे React इस्तेमाल करने वाले HTML route project के कुछ HMR case टूट गए
    • संबंधित issue: #30678
  • odd-length slice

    • Bun का Zig helper reinterpretSlice(u16, bytes) @divTrunc का इस्तेमाल करता था, इसलिए आख़िर का odd byte अनदेखा हो जाता था
    • Rust का bytemuck::cast_slice odd length पर panic करता है
    • Blob.text() में UTF-16 BOM के बाद odd byte आने पर string लौटने के बजाय process panic करने वाला regression था
    • fix में &buf[..buf.len() & !1] से odd byte को फिर से ignore किया गया
    • संबंधित issue: #31188
  • Bounds checks

    • macOS और Linux का Zig code ReleaseFast से compile हुआ था, इसलिए bounds check हट गए थे, जबकि Rust release build में bounds check बने रहते हैं
    • Bun module resolver के overflow block का size placeholder 64 पर ही रह गया, जिससे ceiling 84 लाख interned filenames से घटकर 270,272 हो गई
    • port किया गया ptrs[4095] off-by-one असली project में reachable हो गया, और Rust ने out-of-bounds write करने के बजाय panic किया
    • संबंधित issue: #31503
  • comptime format strings

    • Zig के Output.pretty में fmt comptime है, इसलिए <r>, <d> color marker argument substitution से पहले ANSI escape में बदल जाते हैं
    • Rust function में comptime parameter नहीं था, इसलिए उसने marker को तैयार string पर process किया और arguments को भी ग़लत तरह से rewrite कर दिया
    • bun update -i में OSC 8 hyperlink termination और आख़िर का <r> marker टकरा गए, जिससे r text के रूप में छप गया
    • Rust में macro bun_core::pretty!("<r>{}<r>", hyperlink) की ज़रूरत पड़ी
    • संबंधित issue: #30693

ठीक किए गए bug और memory leak

  • Bun v1.4.0 ने v1.3.14 में reproduce होने वाले 128 bug ठीक किए
  • इसका दायरा memory leak, crash, और ग़लत रंग वाले help text तक फैला था
  • Rust का Drop value के scope से बाहर जाते ही अपने-आप drop function को call करता है
  • Zig में हर call site पर defer जोड़ना पड़ता था, इसलिए cleanup छूट जाना या duplicate cleanup होना आसान था
  • Rust का Drop hidden control flow को स्वीकार करने के बदले आम footgun कम करने का विकल्प है
  • Drop ने error handling code में file path से जुड़े कई memory leak ठीक किए
  • Bun का LeakSanitizer integration बेहतर किया गया, ताकि सभी native code memory allocations को track किया जा सके
  • सभी instrumentable memory leak ठीक कर दिए गए
  • Bun.build() leak में सुधार

    • पहले Bun v1.3.14 में हर in-process Bun.build() call पर parsed source text और AST symbol table build की lifetime से ज़्यादा देर तक बचे रहते थे, जिससे हर बार कई MB leak होते थे
    • एक ही process में 60-module project को 2,000 बार bundle करने वाले test में v1.3.14 हर build पर लगभग 3MB लगातार leak करता रहा
    • Bun v1.4.0 में memory usage स्थिर हो गई
    • | Builds | Bun v1.3.14 | Bun 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 |

binary size, stack usage, performance

  • Rust rewrite के शुरुआती बदलावों से ही binary size कम हो गया
    • Windows: 3.8 MB कम
    • macOS: 5.5 MB कम
    • Linux: 6.8 MB कम
  • इसका मुख्य कारण Zig code में comptime का बहुत ज़्यादा इस्तेमाल था
  • बाद में identical code folding, ICU के unused data को हटाना, और libicu के कुछ हिस्सों को zstd dictionary के साथ lazy decompression में बदलना भी लागू किया गया
  • Rust rewrite, ICU बदलाव, और identical code folding को मिलाकर Linux और Windows में Bun binary size लगभग 20% कम हो गया
Version Platform Size
Bun v1.4.0 canary Windows 76 MB
Bun v1.3.14 Windows 94 MB
Bun v1.4.0 canary Linux 70 MB
Bun v1.3.14 Linux 88 MB
  • TOML parser और Bun के recursive-descent parser अब कम stack space इस्तेमाल करते हैं
  • Rust का LLVM IR codegen stack variables के लिए llvm.lifetime.start और llvm.lifetime.end intrinsic emit करता है, जिससे LLVM stack slot को reuse कर सकता है
  • पहले Zig के open issue को workaround करने के लिए खासकर बड़े function को हाथ से कई छोटे function में refactor किया जाता था
  • Rust, C/C++ और Rust के बीच cross-language link-time optimization को support करता है, जिससे भाषाओं के बीच inlining संभव होती है
  • Linux x64 benchmark

    • Bun v1.3.14 और Bun v1.4.0 की तुलना Linux x64 EC2 Xeon Platinum 8488C पर की गई
    • HTTP throughput को oha से, और app workload को hyperfine से मापा गया
    • | server | Bun v1.3.14 | Bun v1.4.0 | Δ |
    • | --- | ---: | ---: | ---: |
    • | Bun.serve | 169.6k req/s | 177.7k req/s | +4.8% |
    • | node:http | 103.8k req/s | 108.5k req/s | +4.5% |
    • | Elysia | 158.9k req/s | 163.3k req/s | +2.8% |
    • | express | 64.5k req/s | 66.6k req/s | +3.2% |
    • | fastify | 91.5k req/s | 95.9k req/s | +4.8% |
    • | workload | Bun v1.3.14 | Bun v1.4.0 | Δ |
    • | --- | ---: | ---: | ---: |
    • | next build | 13.62 s | 13.03 s | +4.5% |
    • | vite build | 1.69 s | 1.65 s | +2.2% |
    • | tsc -b --force | 0.94 s | 0.89 s | +4.7% |

वास्तविक उपयोग के मामले और रिलीज़ स्थिति

  • Prisma ने Bun के Rust rewrite पर Prisma Compute public beta लॉन्च किया
  • Prisma के अनुसार, VM pause/resume के बाद recover न होने वाले connection pool और memory leak failure mode को Rust rewrite में टेस्ट किया गया, और बताया गया कि इस failure mode को अच्छी तरह handle किया गया
  • Claude Code v2.1.181 और 17 जून रिलीज़ के बाद के वर्ज़न Rust पोर्ट वाले Bun का उपयोग करते हैं
  • Claude Code का Linux startup 10% तेज़ हुआ, और इसके अलावा ज़्यादातर users को शायद ही कोई अंतर महसूस हुआ
  • Bun v1.3.14 Zig में लिखा गया आख़िरी Bun वर्ज़न है
  • Bun v1.4.0 Rust में लिखा गया पहला Bun वर्ज़न है, और canary के रूप में उपलब्ध है

टीम को मिले टूल और बाकी काम

  • नया Rust codebase मौजूदा Zig codebase के बहुत समान रूप को बनाए रखता है
  • इसे इस तरह लिखा गया कि जो लोग मूल Zig code को समझते हैं, वे machine-translated Rust code को भी समझ सकें
  • Rust rewrite PR review इस तरह किया गया कि एक adversarial review agent यह जाँच सके कि Zig और Rust के बीच mismatch, porting guide, और lifetime guide के पालन में कहीं कमी तो नहीं है, और इंसान बड़ी मात्रा में code को side-by-side पढ़ सकें
  • Bun v1.4, Bun को और तेज़ व छोटा बनाता है, memory usage कम करता है, और stability सुधारने के लिए टूल देता है
    • Rust borrow checker
    • Miri
    • LeakSanitizer
    • parser के लिए 24/7 coverage-guided fuzzing
  • अभी भी कुछ हिस्से refactor किए जाने बाकी हैं, और bun-unsafe-audit लिंक किया गया है
  • एक इंजीनियर ने Fable और Claude Code को क़रीब से मॉनिटर किया, और सिर्फ़ 11 दिनों में उस स्थिति तक पहुँच गया जहाँ पूरा test suite सभी platforms पर pass हो गया

1 टिप्पणियां

 
GN⁺ 3 시간 전
Lobste.rs की राय
  • अगर C++ इस्तेमाल किया जाता, तब भी Bun के लिए वह एक तर्कसंगत विकल्प लगता। constructors और destructors मिल जाते, और extern "C" wrapper code का काफी हिस्सा हटाया जा सकता था, लेकिन फिर भी code review से लागू होने वाली style guide पर निर्भर रहना पड़ता, और ASAN होने पर भी memory corruption और leaks आते ही रहते
    दिलचस्प बात यह है कि Node.js C++ के साथ भी ठीक चलता है, लेकिन मैंने Bun को कभी गंभीर project नहीं माना। अब यह Anthropic की marketing team के test bench जैसा लगता है, इसलिए मैं इससे दूर ही रहूँगा
    • Node में भी उसके अपने library code से निकले memory safety CVE साफ़ तौर पर रहे हैं। बस "nodejs memory cves" खोजें, कई मामले तुरंत मिल जाते हैं
    • यह कहना कि Node C++ पर अच्छी तरह चलता है, लगभग वैसा ही है जैसा कहना कि Bun Zig पर अच्छी तरह चल रहा था। Node पर ज़्यादा ध्यान और users हैं, इसलिए समस्याएँ जल्दी सामने आती हैं, लेकिन आखिरकार दोनों की हालत यही है कि “अगर बहुत सावधानी बरती जाए और कोई गलती न करे, तो यह पूरी तरह काम करता है”
      spoiler यह है कि असल दुनिया में लोग इतने सावधान नहीं होते और गलतियाँ भी करते हैं
  • यह कहना कि “Bun के Rust code का लगभग 4% unsafe blocks के अंदर है, और उनमें से 78% सिर्फ एक line के हैं” सुनने में भरोसा दिलाने वाली बात लगती है, लेकिन unsafe block एक line का है या नहीं, यह मायने नहीं रखता। अगर उसके अंदर safety guarantees टूटती हैं, तो block के बाहर का सारा code भी संभावित रूप से soundness खो सकता है
    Bun के Rust port के शुरुआती merge में इसी तरह की साफ़ unsoundness शामिल थी: https://github.com/oven-sh/bun/issues/30719
    उस issue पर maintainers ने CI में Rust के Miri tool को चालू करके प्रतिक्रिया दी, और लेख के “What's Next” में भी Miri (which runs for a growing chunk of code in CI) शामिल है, इसलिए लगता है कि उस दिशा में काम हो रहा है
    निष्पक्ष रूप से देखें तो safety violations वाला Rust भी, जिस Zig code को उसने बदला है उसकी गुणवत्ता पर निर्भर करते हुए, ज़्यादा maintainable हो सकता है। फिर भी प्रति unsafe block code lines कोई quality metric नहीं है, खासकर तब जब उन blocks के साथ दूसरी coding practices, expertise, या automated checks न हों
    • वह वाक्य मुझे भरोसा दिलाने के लिए नहीं, बल्कि यह कहने के ज़्यादा करीब लगता है कि unsafe blocks porting process से नहीं, बल्कि project requirements से आते हैं। अगर आप C libraries को call करते हैं, तो unsafe blocks चाहिए ही, और सिर्फ refactoring से उन्हें हटाया नहीं जा सकता
      हाँ, अगर उन C libraries को भी फिर से लिखा जाए तो बात अलग है, लेकिन उसे बाद में देखा जा सकता है
  • Bun की सबसे दिलचस्प बातों में से एक यह है कि मूल रूप से यह एक engineer द्वारा उम्मीद से कहीं ज़्यादा काम कर दिखाने की कहानी है। Jarred ने पहले इसका श्रेय Zig को दिया था, और इस बार Claude को दे रहा है, लेकिन अगर इसका श्रेय Jarred खुद या उसकी work ethic को दिया जाए तो भी अजीब नहीं होगा। यह छोटे team की ताकत हो सकती है, या फिर इस वजह से कि वे पहले से मौजूद चीज़ों को फिर से लिख और implement कर रहे हैं
    “Bun is joining Anthropic” घोषणा में Jarred ने कहा था कि Bun पर काम करने के लिए और engineers रखे जा रहे हैं, लेकिन सिर्फ GitHub देखें तो Bun team उल्टा छोटी हुई लगती है। इससे क्या निष्कर्ष निकले, यह साफ़ नहीं, बस इतना कि “Bun एक छोटा team है”
  • एक तरफ कहा गया कि “rewrites एक भयानक विचार हैं”, और तुरंत बाद rewrite कर भी दी गई
    तरीका अपने आप में दिलचस्प है, लेकिन लेख marketing article जैसा लगता है। इसमें लागत कितनी आई, उसका विश्लेषण कम है; Rust rewrite के जोखिमों पर बात नहीं है; और शुरू में rewrite की ज़रूरत क्यों पड़ी, इसका ठोस विवरण भी कमज़ोर है। मेरा अनुमान है कि यह Zig की no ai policy की वजह से हुआ हो, या Anthropic के भीतर Rust पर फोकस करने की नीति रही हो
    • लागत के बारे में कम से कम यह हिस्सा प्रासंगिक लगता है: “merge से पहले 5.9 billion uncached input tokens, 690 million output tokens, और 72 billion cached input token reads इस्तेमाल हुए, जिनकी API pricing के हिसाब से कीमत लगभग $165,000 थी”
      और rewrite क्यों हुई, इस पर मुझे लगता है कि लेख काफ़ी सुसंगत कहानी बताता है। Bun ने समस्या पकड़ने के लिए काफ़ी उपाय किए, फिर भी crashes आते रहे, और developers ऐसा तरीका चाहते थे जो इस तरह की समस्याओं को ज़्यादा व्यवस्थित ढंग से रोके
      शुरुआती योजना कुछ खास coding styles को और सख्ती से लागू करने और smart pointers अपनाने की थी, लेकिन Jared का मानना था कि custom smart pointers, Rust की तुलना में, इस्तेमाल में बदतर हैं और कोई guarantees भी नहीं देते। फिर बात यहाँ तक पहुँची कि “क्यों न एक हफ्ते तक टेस्ट करें कि Anthropic का नया model Bun को Rust में फिर से लिख सकता है या नहीं?” और जैसे-जैसे test suite pass rate ऊँचा गया, बात “शायद किया जा सकता है” से “इसे merge करेंगे” तक पहुँच गई
      यानी शुरुआत से Rust rewrite का फैसला नहीं था, बल्कि मामला ज़्यादा इस तरह था: “Rust समस्या का हल देती दिखती है, लेकिन rewrite की लागत के कारण हम यह नहीं कर सकते। लेकिन LLM porting आज़माने पर संभावना दिख रही है। तो फिर LLM rewrite करते हैं”
    • “merge से पहले 5.9 billion uncached input tokens, 690 million output tokens, और 72 billion cached input token reads इस्तेमाल हुए, जिनकी API pricing के हिसाब से कीमत लगभग $165,000 थी”
    • rewrite की वजह काफ़ी जायज़ लगती है। लगातार memory safety issues और अंतहीन whack-a-mole style bug fixing का डर था, और कुछ engineers शायद इसका कोई दूसरा जवाब चुनते, लेकिन LLM की मदद से Rust rewrite चुनना भी समस्या का एक समाधान है
    • यह निश्चित रूप से marketing article जैसा पढ़ा जाता है। चाहे इरादा रहा हो या नहीं। लेकिन असल में लागत निकालना लगभग नामुमकिन है, खासकर अगर developers को release से पहले Anthropic models तक पहुँच मिली हो। फिर भी, अगर हम जैसे सामान्य लोग आज के Claude models के साथ उसी पैमाने पर दोबारा यह काम करें, तो लागत का अनुमान लगाया जा सकता है
  • इन bugs को एक-एक करके ठीक करते रहने के बजाय, अपने users के लिए बेहतर करना और ऐसी bugs दोबारा न हों इसके लिए व्यवस्थित रोकथाम करना एक शानदार कारण है। फिर भी, अगर वजह सिर्फ “Rust का माहौल अच्छा है” भी होती, तो भी मैं इसे स्वीकार कर लेता
    यह कर दिखाने के लिए Jarred, Bun team, और Anthropic को बधाई