Bun’ı Rust ile yeniden yazmak
(bun.com)- 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,tlsgibi 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:zlibiçinde async.write()sırasında.reset()çağrısından kaynaklanan heap-use-after-freenode:http2içinde yeniden girişli JS callback’in hashmap rehash tetiklemesiyle iç stream pointer’larının geçersiz hale geldiği bir use-after-freeUDPSocket.send()vesendMany()içindevalueOf()veyatoString()callback’ininArrayBuffer’ı detach etmesi sorunuBuffer#copy,Buffer#filliçinde argüman coercion sırasındaArrayBufferdetach veya resize nedeniyle oluşan crash ve out-of-bounds readcrypto.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
BroadcastChannelveyaMessagePorteşzamanlı erişimi sırasındaMessageEventrace 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
deferile 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 RustDropkullanı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
unsafekullanı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
.zigdosyalarınıPORTING.mdveLIFETIMES.tsvdoğrultusunda mekanik biçimde.rsdosyalarına port etme - crate bazında derleyici hatalarını düzeltme
bun test,bun buildgibi 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.mdolarak 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.tsviç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_closeasenkron olmasına rağmenBox<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 negatifnsecüreten bir timespec hatası unwrap_orargümanını eager değerlendirdiği içincolor-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
.zigdosyası taşınmadan önce süreç önce 3 dosya üzerinde doğrulandı- 1 uygulayıcı
.rsdosyalarını yazdı - 2 incelemeci,
.zigile davranışın eşleştiğini vePORTING.md,LIFETIMES.tsvkurallarına uyulduğunu doğruladı - 1 fixer önerileri uyguladı
- 1 uygulayıcı
- 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ışındakigitkomutları vecargogibi 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ş
grepbile 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ı
- Her crate içinde
- 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 checkgeçtikten sonra sırasıyla link hataları, başlangıçtan hemen sonra oluşan panic’ler,bun --versionvebun 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-runve 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
- Debian 13 x64:
- 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ı
.patchdosyaları- 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’ü
unsafeblock içinde yer alıyor- Yaklaşık 13.000
unsafeanahtar sözcüğü - Yaklaşık 27.000 satır / toplam yaklaşık 780.000 satır
unsafeblock’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
- Yaklaşık 13.000
- JavaScriptCore gibi C/C++ kütüphaneleri kullanılmaya devam edildiği için, saf Rust projelerine göre
unsafemiktarı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
assertyapı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
- Zig'in
-
Tek uzunluklu slice
- Bun'ın Zig helper'ı
reinterpretSlice(u16, bytes), trailing tek byte'ı yok saymak için@divTrunckullanı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
- Bun'ın Zig helper'ı
-
Bounds check'ler
- macOS ve Linux'taki Zig kodu
ReleaseFastile 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
64olarak 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
- macOS ve Linux'taki Zig kodu
-
comptimeformat string'leri- Zig'deki
Output.prettyiçindefmt,comptimeolduğ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 -iiçinde OSC 8 hyperlink termination ile sondaki<r>işareti çakıştı vermetin olarak basıldı- Rust'ta
bun_core::pretty!("<r>{}<r>", hyperlink)macro'su gerekiyordu - İlgili issue: #30693
- Zig'deki
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 olarakdropfonksiyonunu çağırır - Zig'de ise her call site'a
defereklemek gerekir; bu da cleanup'ın atlanmasını veya iki kez yapılmasını kolaylaştırıyordu - Rust'ın
Dropyaklaşı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 |
- Önceki Bun v1.3.14'te, process içindeki her
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.startvellvm.lifetime.endintrinsic'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
Lobste.rs yorumları
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.
Spoiler: Gerçekte o kadar dikkatli olunmuyor ve hatalar da yapılıyor.
unsafeblokları içinde ve bunların %78’i tek satırlık” ifadesi rahatlatmaya yönelik gibi görünüyor, ama birunsafebloğ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.
unsafebloklarının portlama sürecinden değil proje gereksinimlerinden kaynaklandığını söylüyor gibi. Bir C kütüphanesi çağırıyorsanızunsafeblokları 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 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.
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.
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.
Bunu başaran Jarred’ı, Bun ekibini ve Anthropic’i tebrik ederim.