2 puan yazan GN⁺ 3 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • Zig ile başlayan Bun, aylık 2.200 milyondan fazla indirme alan bir runtime’a dönüştü; ancak GC tabanlı JavaScript motoru ile manuel bellek yönetiminin iç içe geçmesi, tekrarlanan kararlılık sorunlarını Rust’a geçişin tetikleyicisi yaptı
  • İnsanların 535.496 satırlık Zig kodunu 1 yıl boyunca taşımak yerine, Claude Code’un yaklaşık 50 dinamik iş akışı ve en fazla 64 Claude örneği 11 gün boyunca paralel çalıştırıldı
  • Port etme süreci PORTING.md, LIFETIMES.tsv, 1 implementer ve en az 2 adversarial reviewer ile mevcut TypeScript test paketi üzerinden doğrulandı; 6 platformlu CI’da %100 başarı sağlandı
  • Rust’a geçişten sonra Bun v1.4.0, v1.3.14’te yeniden üretilebilen 128 hatayı düzeltti, instrument edilebilir bellek sızıntılarının tamamını giderdi ve Linux ile Windows ikili dosya boyutunu yaklaşık %20 küçülttü
  • Bun v1.3.14 son Zig sürümü; v1.4.0 ise canary kanalında sunulan ilk Rust sürümü ve ekip kararlılığı artırmak için borrow checker, Miri, LeakSanitizer ve 7/24 coverage tabanlı fuzzing kullanıyor

Zig ile başlayan Bun ve kararlılık sorunları

  • Bun, esbuild’in JavaScript·TypeScript transpiler’ının Go’dan Zig’e satır satır port edilmesiyle başlayan bir projeydi
  • İlk Zig kodu 16 Nisan 2021’de yazıldı; Zig’in düşük seviyeli kontrolü ve performans odaklı tasarımı, Bun’ın ilk uygulamasını mümkün kıldı
  • İlk Bun, tek bir kişi tarafından 1 yıl boyunca Zig ile yazıldı ve kapsamı çok genişti
    • JavaScript, TypeScript, CSS transpiler·minifier·bundler
    • npm uyumlu paket yöneticisi
    • Jest benzeri test runner
    • Node.js·TypeScript uyumlu modül çözümleme
    • HTTP/1.1·WebSocket istemcisi
    • fs, net, tls gibi Node.js API implementasyonları
  • Bugün Bun CLI aylık 2.200 milyondan fazla kez indiriliyor; Claude Code ve OpenCode bunu runtime olarak kullanıyor ve Vercel, Railway, DigitalOcean gibi şirketler 1st-party destek sağlıyor

Tekrarlayan bellek güvenliği hataları

  • Bun v1.3.14’te düzeltilen örnek hatalar arasında use-after-free, double-free, bellek sızıntısı, out-of-bounds erişim ve race condition yer alıyor
    • node:zlib içinde async .write() sırasında .reset() çağrısından kaynaklanan heap-use-after-free
    • node:http2 içinde yeniden girişli JS callback’in hashmap rehash tetiklemesiyle iç stream pointer’larının geçersiz hale geldiği bir use-after-free
    • UDPSocket.send() ve sendMany() içinde valueOf() veya toString() callback’inin ArrayBuffer’ı detach etmesi sorunu
    • Buffer#copy, Buffer#fill içinde argüman coercion sırasında ArrayBuffer detach veya resize nedeniyle oluşan crash ve out-of-bounds read
    • crypto.scrypt, tlsSocket.setSession(), fs.watch() ile ilgili bellek sızıntıları
    • CSS parser’da vendor prefix ve multi-layer background işlenirken ortaya çıkan double-free
    • BroadcastChannel veya MessagePort eşzamanlı erişimi sırasında MessageEvent race condition crash’i
  • Daha önce de kararlılığı artırmak için çeşitli önlemler kullanılıyordu
    • Zig compiler’a Address Sanitizer desteği yamalandı ve her commit’te ASAN test paketi çalıştırıldı
    • Windows için Zig safety-checked ReleaseSafe build’leri dağıtıldı
    • Fuzzilli ile Bun runtime API’si 7/24 fuzzing’e tabi tutuldu
    • Çok sayıda uçtan uca bellek sızıntısı testi yürütüldü
  • Sorunun Zig’in kendisi olduğu düşünülmüyor; GC değerleri ile manuel yönetilen belleği birlikte ele alma gereksinimi, kararlılık sorunlarının başlıca kaynağıydı

Neden Rust seçildi

  • JavaScript bir GC dili ve JavaScriptCore ile V8 gibi motorlar, istisna işleme ve GC konusunda katı kurallara sahip
  • Zig, C gibi belleği otomatik yönetmiyor; constructor·destructor yok ve cleanup çoğunlukla her çağrı noktasında defer ile açıkça belirtilmek zorunda
  • Bun’da GC değerleri ile manuel yönetilen değerlerin lifetime’ını doğru yönetmek, kararlılık sorunlarının büyük bir kaynağıydı
    • Ayrılan baytların nerede serbest bırakıldığını doğrulamak gerekiyordu
    • Yalnızca bir kez serbest bırakıldığından emin olunmalıydı
    • JavaScript istisna işlemenin doğru kontrol edilmesi gerekiyordu
    • GC pointer’larının conservative stack scanner tarafından görülebildiği doğrulanmalıydı
  • Zig’in cleanup yaklaşımı açık defer, errdefer; C++ destructor ve move kullanırken Rust Drop kullanır
  • Bun’ın mevcut Zig kodunda arena lifetime, reference counting ve çok dikkatli inceleme iç içe kullanılıyordu
  • Ownership kuralları stil rehberi ve kod incelemesiyle de zorlanabilir; ancak Rust’ın güvenli kodunda use-after-free, double-free ve hata yolunda atlanan free işlemleri derleyici hatasına dönüşür
  • Bun kodunun yaklaşık %20’si C++ ve içinde birden çok C/C++ kütüphanesi gömülü
    • JavaScriptCore
    • uWebSockets ve usockets
    • lshpack ve lsquic
    • BoringSSL
    • SQLite
  • C++ da bir seçenek olabilirdi; ancak yine stil rehberi ve kod incelemesine bağımlı kalınacaktı ve ASAN bulunsa bile bellek bozulmaları ile sızıntılar yine de oluşabilirdi

Yeniden yazım stratejisi: tek seferde, mekanik olarak

  • Mevcut Bun Zig kodu yorumlar hariç 535.496 satırdı ve geleneksel bir yeniden yazımın, küçük bir mühendis ekibinin yaklaşık 1 yılını alacağı değerlendirildi
  • Hata düzeltmeleri, güvenlik yamaları ve özellik geliştirmeleri 1 yıl durdurulamayacağı için, kullanıcı davranışındaki değişikliği en aza indiren mekanik port etme en düşük riskli yaklaşım olarak seçildi
  • Bun’ın test paketi TypeScript ile yazılmıştı; bu yüzden runtime’ın uygulama diline bağlı değildi
  • Artımlı yeniden yazım, geçici kod üretip bunun sonra silinmesini ummayı gerektirdiği için kısa ve orta vadede sancılı bulunarak her şey tek seferde taşındı
  • Rust kodunun, Zig kodu transpile edilmiş gibi görünmesi hedeflendi; Bun v1.4 sonrasında ise unsafe kullanımını kademeli azaltıp daha idiomatic Rust’a refactor etme yönü benimsendi

Claude Code dinamik iş akışları

  • Rust yeniden yazımı için Claude Code içinde yaklaşık 50 dinamik iş akışı 11 gün boyunca aralıksız çalıştı
  • İş akışları, porting rehberi yazımından dosya dönüşümüne, derleme hatalarının düzeltilmesine, subcommand’lerin geri kazanılmasına, tüm testlerin geçirilmesine ve büyük ölçekli cleanup’a kadar uzandı
    • Zig desenleri ve tiplerini Rust desenleri ve tiplerine eşleyen bir porting rehberi oluşturma
    • Tüm .zig dosyalarını PORTING.md ve LIFETIMES.tsv doğrultusunda mekanik biçimde .rs dosyalarına port etme
    • crate bazında derleyici hatalarını düzeltme
    • bun test, bun build gibi subcommand’lerin çalışmasını geri kazandırma
    • Tüm test paketini geçme
    • Büyük ölçekli refactor ve cleanup
  • Sürecin büyük bölümünde insanlar iş akışı çıktısını okuyup sorunları ve hataları doğruladı; Claude’un döngüleri düzeltmesi için prompt’lar buna göre ayarlandı
  • Ön çalışma olarak Claude ile yaklaşık 3 saat boyunca Zig kod tabanındaki desenlerin Rust’a nasıl eşleneceği tartışıldı ve bu sonuç PORTING.md olarak serileştirildi
  • Manuel bellek yönetimi koduna Rust lifetime’ları eklemek için tüm struct field’larının lifetime’ını analiz eden bir iş akışı çalıştırıldı
    • Karmaşık lifetime’a sahip field’ları bulma
    • Lifetime önerme
    • 2 adversarial review agent tarafından inceleme
    • Geri bildirimleri yansıtıp LIFETIMES.tsv içine kaydetme

Düşmanca inceleme yöntemi

  • Her uygulayıcı Claude için ayrı bir context window içinde düşmanca incelemeci Claude yer aldı; incelemeciye yalnızca diff verilerek kodun hatalı olduğu varsayımıyla bug bulması talimatı verildi
  • Temel yapı 1 uygulayıcı, en az 2 düşmanca incelemeci ve 1 fixer’dan oluşuyordu
  • İncelemecilerin gerçekten yakaladığı hataların tümü derlemeden geçiyordu ancak davranışsal sorunlar içeriyordu
    • uv_close asenkron olmasına rağmen Box<uv::Pipe> match arm sonunda drop edildiği için, libuv’nin freed memory tutmasına yol açan use-after-free ve double-free
    • Negatif tam sayı olmayan file time değerinde trunc() kullanıldığında negatif nsec üreten bir timespec hatası
    • unwrap_or argümanını eager değerlendirdiği için color-mix() percentage atlama durumunda panic’e neden olan hata
  • İnsan incelemesinde olduğu gibi, uygulayıcı ile incelemecinin context’i ayrılarak, uygulayıcının merge istemesinden doğabilecek önyargı azaltıldı

Büyük ölçekli port yürütme ve paralelleştirme

  • Toplam 1.448 .zig dosyası taşınmadan önce süreç önce 3 dosya üzerinde doğrulandı
    • 1 uygulayıcı .rs dosyalarını yazdı
    • 2 incelemeci, .zig ile davranışın eşleştiğini ve PORTING.md, LIFETIMES.tsv kurallarına uyulduğunu doğruladı
    • 1 fixer önerileri uyguladı
  • Tüm dosyaların port edilmesinin başında, birden fazla Claude git stash, git stash pop, git reset HEAD --hard çalıştırarak birbirleriyle çakıştı
  • Ardından iş akışına git stash, git reset, belirli dosya commit’i dışındaki git komutları ve cargo gibi yavaş komutları yasaklayan kurallar eklendi
  • Sonunda 4 iş akışı shard’ı ve 4 worktree kullanıldı; her shard’da 16 Claude dosyaları commit edip push etti
  • Paralelleştirme ve ön hazırlık sayesinde, zirvede Claude dakikada yaklaşık 1.300 satır kod yazdı
  • Port branch’inde merge hariç commit sayısı 6.502, en yoğun saatte 695 commit vardı ve son landed diff +1.009.272 satırdı
  • EC2 instance’ının varsayılan IOPS değeri artırılmadığı için, tek bir yavaş grep bile disk okuma-yazmasını dakikalarca durduran bir soruna yol açabiliyordu

Derleme hataları ve crate ayrımı

  • Tüm kod yazıldıktan sonra Claude iş akışı derleyici hatalarını düzeltti
  • Zig kod tabanı fiilen tek bir compilation unit’ti ve Rust kodu daha hızlı derleme için yaklaşık 100 crate’e bölünmek istendi
  • En zorlu hata kategorisi döngüsel bağımlılıklar oldu
    • Rust yeniden yazımından hemen önceki crate ayırma PR’ı tek başına yeterli değildi
    • Ayrı bir iş akışı, döngüsel bağımlılığı olan kodun nereye konacağını sınıflandırıp kayda geçirdi
    • Başka bir iş akışı da ilgili refactoring’i gerçekleştirdi
  • Döngüsel bağımlılıklar çözüldükten sonra yaklaşık 16.000 derleyici hatası ortaya çıktı
  • Bu hatalar crate bazında paralel işlendi
    • Her crate içinde cargo check çalıştırıldı
    • Çıktılar dosya bazında gruplanıp kaydedildi
    • İlgili crate’in derleme hataları düzeltildi
    • 2 düşmanca incelemeci değişiklikleri gözden geçirdi
    • 1 fixer düzeltmeleri uyguladı
  • Claude’un “tüm crate’leri derlenebilir hale getirelim” ifadesini function stub üretmek olarak yorumladığı bir false start da yaşandı
  • Uzun açıklama yorumlarıyla workaround’ları meşrulaştırma eğilimi görülünce, “paragraf uzunluğunda yorum gerekiyorsa kod yanlıştır ve kod düzeltilmelidir” şeklinde bir inceleme kuralı eklendi

Testlerin geçilmesine kadar olan süreç

  • cargo check geçtikten sonra sırasıyla link hataları, başlangıçtan hemen sonra oluşan panic’ler, bun --version ve bun test <file> çalıştırma sorunları çözüldü
  • CLI subcommand bazındaki hata stacktrace’leri dosyalara kaydedildi ve uygulayıcı-incelemeci-fixer döngüsüyle düzelten bir iş akışı kullanıldı
  • Test dosyası iş akışı, yaklaşık 100 rastgele test dosyasını 4 worktree arasında shard ederek, her başarısızlık için stacktrace ve hataları kaydedip düzeltti
  • Test suite içinde debug build’de timeout olabilen memory leak testleri ve entegrasyon testleri vardı
    • next dev çalıştırıp hot module reloading’in 100 değişikliği algıladığını doğrulayan test
    • TCP socket azami sayısını tüketen stress test
    • Gigabayt düzeyinde disk okuma-yazma testi
    • Yaklaşık 10 bin process spawn eden test
  • İzolasyon için systemd-run ve cgroups ile bellek-CPU kullanımı sınırlandı ve pid namespace ayrıldı
  • Buna rağmen makine birkaç kez disk alanı yetersizliğinden çöktü
  • İlk CI çalıştırmasından iki gün sonra başarısız test dosyası sayısı 972’den 23’e düştü; bundan bir buçuk gün sonra Linux tamamen green oldu
  • Sonuçta 6 platformda CI üzerindeki tüm testler geçti
    • macOS x64
    • macOS arm64
    • Linux x64
    • Linux arm64
    • Windows x64
    • Windows arm64
  • %100 test geçişinden sonra, testlerin gerçekten çalıştırıldığı ve skip edilmediği insanlar tarafından manuel olarak doğrulandı ve ardından merge edildi
  • main’e merge edildiği an versioned release değildi; release edecek kadar güven henüz yoktu, ancak yeniden yazıma odaklanacak kadar güven oluşmuştu

Test ölçeği ve maliyet

  • 11 gün boyunca, 3 Mayıs’tan 14 Mayıs’taki merge’e kadar 6.778 commit üretildi
  • Testler silinmedi veya skip edilmedi
  • Platform bazında test ölçeği şöyleydi
    • Debian 13 x64: expect() 1.386.826 kez, 60.624 test, 4.174 dosya
    • macOS 14 arm64: expect() 1.259.953 kez, 58.850 test, 4.175 dosya
    • Windows 2019 x64: expect() 1.007.544 kez, 57.337 test, 4.173 dosya
  • Pre-merge çalışmalarında 5,9 milyar uncached input token, 690 milyon output token ve 72 milyar cached input token read kullanıldı
  • API fiyatlandırmasına göre maliyet yaklaşık 165 bin dolar oldu
  • İnsanlar doğrudan yapsaydı, tüm kod tabanının context’ine hakim 3 mühendisin yaklaşık 1 yıla ihtiyaç duyacağı değerlendirildi
  • Kullanılan model pre-release Claude Fable 5 idi ve Bun’ın 2025 Aralık’ta Anthropic tarafından satın alındığına dair bir disclosure yer aldı

Güvenlik incelemesi, fuzzing ve unsafe durumu

  • Rust portu merge edildikten sonra Claude Code Security ile 11 tur güvenlik incelemesi tamamlandı ve bulgular ele alındı
  • Bun’ın tüm parser’ları için 7/24 coverage tabanlı fuzzing eklendi
    • JavaScript
    • TypeScript
    • JSX
    • CSS
    • JSON5
    • JSONC
    • TOML
    • YAML
    • Markdown
    • INI
    • Bun Shell script’leri
    • semver aralıkları
    • .patch dosyaları
    • CSS renkleri
  • Fuzzer, bulduğu bug’ları Claude’a gönderiyor; Claude da yeniden üretim ve düzeltmeyi içeren bir PR gönderiyor, insanlar ise PR’ı inceliyor
  • Şimdiye kadar parser çalıştırma sayısı 100 milyar oldu ve bu süreç yaklaşık 15 PR ile sonuçlandı
  • Yazım anı itibarıyla Rust kodunun yaklaşık %4’ü unsafe block içinde yer alıyor
    • Yaklaşık 13.000 unsafe anahtar sözcüğü
    • Yaklaşık 27.000 satır / toplam yaklaşık 780.000 satır
    • unsafe block’larının %78’i tek satırlık ve C++’tan gelen pointer’lar veya C kütüphane çağrılarından oluşuyor
  • JavaScriptCore gibi C/C++ kütüphaneleri kullanılmaya devam edildiği için, saf Rust projelerine göre unsafe miktarının her zaman daha fazla olacağı belirtiliyor

Rust geçişinden sonra bulunan regresyonlar

  • Rust yeniden yazımı büyük çaplı bir değişiklikti ve bilinen 19 regresyona yol açtı; bunların hepsi düzeltildi
  • Bunların çoğu, iki dilde sözdizimi benzer ama anlamı farklı olan kodlardan kaynaklandı
  • debug_assert! içindeki side effect

    • Zig'in assert yapısı bir fonksiyondur; bu yüzden argümanları tüm build'lerde çalıştırılır
    • Rust'ın debug_assert! yapısı ise bir macro'dur; bu yüzden release build'de tüm ifade kaldırılır
    • insert_stale çağrısı release build'de ortadan kayboldu ve React kullanan HTML route projelerinde belirli bir HMR durumu bozuldu
    • İlgili issue: #30678
  • Tek uzunluklu slice

    • Bun'ın Zig helper'ı reinterpretSlice(u16, bytes), trailing tek byte'ı yok saymak için @divTrunc kullanıyordu
    • Rust'taki bytemuck::cast_slice, uzunluk tek olduğunda panic üretir
    • UTF-16 BOM'dan sonra tek sayıda byte gelen Blob.text() için, string döndürmek yerine process'i panic ettiren bir regresyon vardı
    • Düzeltme, tek byte'ı yeniden yok saymak için &buf[..buf.len() & !1] kullanmak oldu
    • İlgili issue: #31188
  • Bounds check'ler

    • macOS ve Linux'taki Zig kodu ReleaseFast ile derleniyordu, bu yüzden bounds check'ler kaldırılmıştı; Rust release build ise bounds check'leri korur
    • Bun module resolver'ın overflow block boyutu placeholder 64 olarak kaldı ve üst sınır 8,4 milyon interned filename'dan 270.272'ye düştü
    • Port edilen ptrs[4095] off-by-one hatası gerçek projelerde ulaşılabilir hale geldi ve Rust, out-of-bounds write yerine panic üretti
    • İlgili issue: #31503
  • comptime format string'leri

    • Zig'deki Output.pretty içinde fmt, comptime olduğu için <r>, <d> renk işaretleri argüman yerleştirmeden önce ANSI escape dizilerine çevrilir
    • Rust fonksiyonunda comptime parametresi yoktu; bu yüzden işaretler tamamlanmış string üzerinde işlendi ve argümanlar da yanlış şekilde yeniden yazıldı
    • bun update -i içinde OSC 8 hyperlink termination ile sondaki <r> işareti çakıştı ve r metin olarak basıldı
    • Rust'ta bun_core::pretty!("<r>{}<r>", hyperlink) macro'su gerekiyordu
    • İlgili issue: #30693

Düzeltilen bug'lar ve bellek sızıntıları

  • Bun v1.4.0, v1.3.14'te yeniden üretilebilen 128 bug'ı düzeltiyor
  • Kapsam; bellek sızıntıları, crash'ler ve yanlış renklendirilmiş help text'e kadar uzanıyor
  • Rust'taki Drop, bir değer scope dışına çıktığında otomatik olarak drop fonksiyonunu çağırır
  • Zig'de ise her call site'a defer eklemek gerekir; bu da cleanup'ın atlanmasını veya iki kez yapılmasını kolaylaştırıyordu
  • Rust'ın Drop yaklaşımı, hidden control flow'u kabul etme karşılığında yaygın footgun'ları azaltmayı hedefliyor
  • Drop, error handling kodundaki file path ile ilgili birden çok bellek sızıntısını düzeltti
  • Bun'ın LeakSanitizer entegrasyonu geliştirildi ve tüm native code memory allocations izlenir hale geldi
  • Instrument edilebilen bellek sızıntılarının tamamı düzeltildi
  • Bun.build() sızıntısında iyileştirme

    • Önceki Bun v1.3.14'te, process içindeki her Bun.build() çağrısında parse edilmiş source text ve AST symbol table, build ömründen daha uzun süre bellekte kalıyor ve her seferinde birkaç MB sızdırıyordu
    • Aynı 60 modüllü projeyi tek bir process içinde 2.000 kez bundle eden testte, v1.3.14 her build başına yaklaşık 3 MB sızdırmaya devam etti
    • Bun v1.4.0'da bellek kullanımı yatay hale geldi
    • | 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 boyutu, stack kullanımı, performans

  • Rust yeniden yazımının ilk değişiklikleri bile binary boyutunu küçülttü
    • Windows: 3.8 MB azalma
    • macOS: 5.5 MB azalma
    • Linux: 6.8 MB azalma
  • Bunun başlıca nedeni, Zig kodunda comptime'ın fazla yoğun kullanılmasıydı
  • Daha sonra Identical Code Folding, ICU'daki kullanılmayan verilerin kaldırılması ve libicu'nun bir kısmının zstd dictionary ile gecikmeli sıkıştırma açılması da uygulandı
  • Rust yeniden yazımı, ICU değişiklikleri ve identical code folding birlikte ele alındığında, Linux ve Windows'ta Bun binary boyutu yaklaşık %20 küçüldü
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 ve Bun'ın recursive-descent parser'ları artık daha az stack alanı kullanıyor
  • Rust'ın LLVM IR codegen'i, LLVM'nin stack slot'larını yeniden kullanabilmesi için stack variable'lara llvm.lifetime.start ve llvm.lifetime.end intrinsic'lerini üretir
  • Daha önce, Zig'deki açık bir issue'yu aşmak için özellikle büyük fonksiyonlar elle daha küçük fonksiyonlara refactor ediliyordu
  • Rust, C/C++ ile Rust arasındaki cross-language link-time optimization'ı destekliyor; bu da diller arası inlining'i mümkün kılıyor
  • Linux x64 benchmark'ları

    • Bun v1.3.14 ile Bun v1.4.0, Linux x64 üzerinde EC2 Xeon Platinum 8488C'de karşılaştırıldı
    • HTTP throughput oha ile, uygulama iş yükü ise hyperfine ile ölçüldü
    • | 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% |

Gerçek kullanım örnekleri ve sürüm durumu

  • Prisma, Bun’ın Rust ile yeniden yazımı üzerinde Prisma Compute public beta sürümünü yayınladı
  • Prisma ekibi, VM pause/resume sonrasında toparlanmayan connection pool ve memory leak failure mode durumlarını Rust ile yeniden yazımda test ettiklerini ve bu failure mode’ların başarıyla ele alındığını belirtti
  • 17 Haziran’da yayınlanan sürüm ve sonrasındaki Claude Code v2.1.181, Rust’a port edilen Bun’ı kullanıyor
  • Claude Code’un Linux startup süresi %10 hızlandı; bunun dışında kullanıcıların çoğunun neredeyse hiçbir fark hissetmediği belirtildi
  • Bun v1.3.14, Zig ile yazılan son Bun sürümü
  • Bun v1.4.0, Rust ile yazılan ilk Bun sürümü ve canary olarak sunuluyor

Ekibin elde ettiği araçlar ve kalan işler

  • Yeni Rust kod tabanı, mevcut Zig kod tabanına çok benzeyen bir yapıyı koruyor
  • Orijinal Zig kodunu anlayan birinin, makine benzeri biçimde çevrilmiş Rust kodunu da anlayabilmesi hedeflenerek yazıldı
  • Rust rewrite PR incelemeleri, saldırgan inceleme yapan bir agent’ın Zig ile Rust arasındaki tutarsızlıkları, porting guide ve lifetime guide uyumunu doğru yakalayıp yakalamadığını kontrol etmek ve insanların çok sayıda kodu side-by-side okuması şeklinde yürütüldü
  • Bun v1.4, Bun’ı daha hızlı ve daha küçük hale getiriyor, bellek kullanımını azaltıyor ve kararlılık iyileştirmeleri için araçlar sağlıyor
    • Rust borrow checker
    • Miri
    • LeakSanitizer
    • parser için 7/24 coverage-guided fuzzing
  • Hâlâ refactor edilecek bölümler var ve bun-unsafe-audit buna bağlı durumda
  • Bir mühendis, Fable ve Claude Code’u yakından izleyerek tüm test paketinin tüm platformlarda geçtiği duruma yalnızca 11 gün içinde ulaştı

1 yorum

 
GN⁺ 3 시간 전
Lobste.rs yorumları
  • C++ kullanılmış olsaydı bile bunun Bun için makul bir seçim olacağını düşünüyorum. Constructor ve destructor’lar kazanılmış, extern "C" wrapper kodunun da büyük kısmı silinebilirdi; ama yine de code review ile dayatılan style guide’lara güvenmek gerekecek, ASAN olsa bile bellek bozulmaları ve sızıntılar yaşanmaya devam edecekti.
    İlginç şekilde Node.js C++ ile de iyi çalışıyor, ama Bun’u hiçbir zaman ciddi bir proje olarak görmedim. Artık Anthropic’in pazarlama departmanı için bir test bench’i gibi görünüyor; bu yüzden uzak durmaya devam edeceğim.
    • Node’un da kendi kütüphane kodundan kaynaklanan bellek güvenliği CVE’leri kesinlikle oldu. Sadece "nodejs memory cves" diye aratınca bile hemen birkaç tane çıkıyor.
    • Node’un C++ ile iyi çalıştığını söylemek, Bun’un Zig ile iyi çalıştığını söylemekle aynı seviyede. Node’un daha fazla ilgisi ve kullanıcısı olduğu için sorunlar daha hızlı ortaya çıkıyor; sonuçta ikisi de “çok dikkatli olursak ve kimse hata yapmazsa kusursuz çalışır” durumunda.
      Spoiler: Gerçekte o kadar dikkatli olunmuyor ve hatalar da yapılıyor.
  • “Bun’un Rust kodunun yaklaşık %4’ü unsafe blokları içinde ve bunların %78’i tek satırlık” ifadesi rahatlatmaya yönelik gibi görünüyor, ama bir unsafe bloğunun tek satır olup olmaması önemli değil. O bloğun içinde güvenlik garantilerini bozarsanız, bloğun dışındaki tüm kod da potansiyel olarak soundness’ı bozulmuş hale gelebilir.
    Bun’un Rust portunun ilk merge’ünde bu tür bariz bir unsoundness vardı: https://github.com/oven-sh/bun/issues/30719
    Bu issue, maintainer’ların CI’da Rust’ın Miri aracını açmasıyla ele alınmış; yazının “What's Next” kısmında da Miri (which runs for a growing chunk of code in CI) yer aldığına göre bu yönde çalışılıyor olması iyi görünüyor.
    Adil olmak gerekirse, güvenlik ihlalleri olan Rust bile, yerine geçtiği Zig kodunun kalitesine bağlı olarak daha bakımı kolay olabilir. Yine de unsafe blok başına kod satırı sayısı bir kalite metriği değildir; özellikle de bu blokların arkasında başka kodlama pratikleri, uzmanlık ve otomatik kontroller yoksa hiç değildir.
    • Bence o cümle rahatlatmaya çalışmaktan ziyade, unsafe bloklarının portlama sürecinden değil proje gereksinimlerinden kaynaklandığını söylüyor gibi. Bir C kütüphanesi çağırıyorsanız unsafe blokları gerekir ve bunu yalnızca refactoring ile ortadan kaldırmanın yolu yoktur.
      Elbette o C kütüphanesini de yeniden yazarsanız mümkün olabilir; ama bu daha sonra değerlendirilebilecek bir şey.
  • Bun’daki en ilginç noktalardan biri, temelde tek bir mühendisin beklenenden çok daha fazlasını başarmasının hikâyesi olması. Jarred başta bunun Zig sayesinde olduğunu söyledi, şimdi de Claude sayesinde diyor; ama Jarred’ın kendisi ya da iş ahlakı sayesinde olduğunu söylemek de garip olmaz. Küçük bir ekibin gücü olabilir, ya da zaten var olan şeyleri yeniden yazıp uyguluyor olmaları gerçeğinden kaynaklanıyor olabilir.
    “Bun is joining Anthropic” duyurusunda Jarred, Bun üzerinde çalışmak için daha fazla mühendis işe alacaklarını söylemişti; ama GitHub’a bakınca Bun ekibi sanki aksine küçülmüş görünüyor. Buradan ne sonuç çıkaracağımı pek bilmiyorum; sadece “Bun küçük bir ekip” diyebilirim.
  • “Yeniden yazmak berbat bir fikir” deyip hemen ardından yeniden yazmaya girişmiş oldular.
    Yöntemin kendisi ilginç, ama yazı bir pazarlama makalesi gibi okunuyor. Ne kadara mal olduğuna dair analiz de eksik, Rust ile yeniden yazmanın riskleri de yok; en başta yeniden yazmanın neden gerçekleştiğine dair somut açıklama da zayıf. Tahmin yürütmek gerekirse bunun nedeni Zig’in no ai policy’si olabilir ya da Anthropic içinde Rust’a odaklanma yönünde bir politika bulunmuş olabilir.
    • Maliyet konusunda şu bölüm en azından ilgili görünüyor: “Merge’den önce 5,9 milyar cache’lenmemiş input token, 690 milyon output token ve 72 milyar cache’lenmiş input token okuması kullanıldı; API fiyatlarıyla yaklaşık 165.000 dolar ediyordu.”
      Neden yeniden yazdıklarına gelince, bence yazı oldukça tutarlı bir hikâye anlatıyor. Bun, sorunları yakalamak için önlemler almasına rağmen crash yaşamaya devam etti ve geliştiriciler bu tür sorunları daha sistematik biçimde engellemenin bir yolunu istediler.
      İlk plan, belirli bir kodlama stilini daha katı biçimde zorunlu kılmak ve smart pointer’lar getirmekti; ama Jared, kendi smart pointer’larının Rust’tan daha kötü kullanılabilirliğe sahip olduğunu ve garanti sunmadığını düşündü. Böylece “Anthropic’in yeni modeli Bun’u Rust ile yeniden yazabilir mi, bir hafta test etsek nasıl olur?” noktasına gelindi; test suite geçme oranı yükseldikçe de akış “denemeye değer”den “merge edeceğim”e dönmüş gibi görünüyor.
      Yani baştan Rust ile yeniden yazmaya karar verilmiş olmaktan ziyade, “Rust sorunlara çözüm sağlıyor gibi görünüyor ama yeniden yazma maliyeti yüzünden yapamıyoruz. Fakat LLM ile portlamayı deneyince mümkün görünüyor. O halde LLM ile yeniden yazmaya gidelim”e daha yakın duruyor.
    • “Merge’den önce 5,9 milyar cache’lenmemiş input token, 690 milyon output token ve 72 milyar cache’lenmiş input token okuması kullanıldı; API fiyatlarıyla yaklaşık 165.000 dolar ediyordu.”
    • Yeniden yazma gerekçesi yeterince haklı görünüyor. Süregelen bellek güvenliği sorunları ve bitmeyen köstebek vurma tarzı bug fix’lerden duyulan korku vardı; bazı mühendisler farklı şekilde yaklaşabilirdi ama LLM ile Rust yeniden yazımını seçmek de soruna yönelik bir çözüm.
    • Kesinlikle pazarlama makalesi gibi okunuyor. İster kasıtlı olsun ister olmasın böyle; ama gerçekte maliyeti hesaplamak neredeyse imkânsız. Özellikle geliştiricilerin yayın öncesi Anthropic modellerine erişimi olduysa. Yine de bugünkü Claude modelleriyle bizim gibi sıradan kişiler o ölçekte bir şeyi yeniden yazsaydı maliyet tahmin edilebilir.
  • Bu bug’ları tek tek düzeltmeye devam etmek yerine, size bağımlı kullanıcılar için daha iyisini yapmak ve bu tür bug’ların tekrar etmesini sistematik olarak engellemek istemek harika bir gerekçe. Yine de gerekçe “Rust havası iyi” olsaydı da kabul ederdim.
    Bunu başaran Jarred’ı, Bun ekibini ve Anthropic’i tebrik ederim.