Bun Install'ın Perde Arkası
(bun.com)- Bun'un paket kurulumu, mevcut paket yöneticilerine kıyasla çok daha hızlı çalışır
- Bu hızlı kurulumun temelinde sistem programlama bakış açısı ve sistem çağrılarını en aza indirme yaklaşımı yer alır
- Zig diliyle yerel kodlama, ikili önbellek kullanımı ve işletim sistemine özel optimizasyonlar gibi ayrıntılı stratejilerle performans artışı sağlanır
- tarball açma ve dosya kopyalama sürecinde de donanım özelliklerinden yararlanan yüksek performanslı yöntemler kullanılır
- Bağımlılık grafiği ve lockfile gibi alanlarda veri yapısı optimizasyonu ile CPU önbellek verimliliği ve bellek erişilebilirliği artırılır
Bun Install neden hızlı?
- Bun'un
bun installkomutu ortalama olarak npm'den 7 kat, pnpm'den 4 kat, yarn'dan 17 kat daha hızlı paket kurulumu sunar - Bunun nedeni yalnızca bir benchmark sonucu değil, paket kurma probleminin JavaScript yerine sistem programlama perspektifiyle ele alınmış olmasıdır
- Sistem çağrılarını azaltma, manifestleri ikili olarak önbellekleme, tarball çıkarma optimizasyonu ve işletim sisteminin yerel dosya kopyalama yetenekleri gibi birçok katmanda agresif performans optimizasyonları uygulanır
Node.js ve paket yöneticisi mimarisinin sınırları
- Node.js'in 2009'da yayınlanmasının ardından, event loop ve thread pool tabanlı asenkron IO modeli paket yöneticilerine de yayıldı
- O dönemde donanım kısıtları nedeniyle (yavaş diskler, yavaş ağlar) asenkron IO ve yüksek sistem çağrısı sıklığı mantıklıydı
- Ancak modern sistemlerde NVMe SSD, hızlı ağ ve yüksek performanslı CPU yaygın hale geldi ve asıl darboğaz artık IO değil, sistem çağrısı ek yükü oldu
Sistem çağrıları ve kip geçişinin maliyeti
- Bir program dosya okuma gibi bir işlem istediğinde, user mode'dan kernel mode'a geçmesi gerekir ve bu süreç pahalı CPU döngüleri (1000~1500 cycles) tüketir
- Paket kurulumu temelde on binlerce ila yüz binlerce sistem çağrısı gerektirdiğinden, yalnızca iş geçiş maliyeti bile saniyeler düzeyinde CPU zamanı harcatabilir
- Örneğin React ve bağımlılıklarını kurarken npm yaklaşık 1 milyon, yarn 4 milyon, pnpm 500 bin, bun ise 160 bin sistem çağrısı kullanır
Mevcut paket yöneticileri ile Bun'un yaklaşımı arasındaki fark
- npm, pnpm ve yarn'ın tamamı Node.js tabanlıdır; yani JavaScript'in birden fazla soyut katman üzerinden çalıştırılması gerekir (
libuv, event loop, thread pool, sistem çağrısı aracılığı) - Bu sırada argüman dönüşümü, worker pool kuyruğu, event loop iş dallanması ve
futex(kilit senkronizasyonu) sistem çağrıları birikerek IO'dan çok sistem çağrısı yönetimini yavaşlatır - Node.js ile yazılmış paket yöneticileri, bu yapısal sınırlamalar nedeniyle gerçek anlamda yerel performansa yaklaşmakta zorlanır
Bun: Zig ile yazılmış yerel kurulum motoru
- Bun, sistem çağrılarını doğrudan yapmak için Zig dilini kullanır ve JavaScript motoru/soyutlama katmanlarını tamamen atlar
- Örneğin dosya okuma, Zig kodunda doğrudan
openat()sistem çağrısını çalıştırıp veriyi hemen döndürür - Böylece on binlerce dosyanın okunması, ek bir thread pool, event loop veya veri dönüştürme süreci olmadan son derece hızlı gerçekleşir
- Benchmark sonuçlarına göre Bun saniyede 146.057 adet
package.jsonokuyabilirken, Node.js 60 bin civarında kalır ve 2 kattan fazla daha yavaştır
Bağımlılık yönetimi ve DNS optimizasyonu
- Bun,
bun installçalışırken bağımlılık analizini yaparken aynı anda DNS prefetch işlemini de asenkron olarak tetikler - Örneğin macOS'ta Apple'ın resmî olmayan async DNS API'si olan
getaddrinfo_async_start()kullanılır ve thread bloklamadan ağ işlemlerinin eşzamanlı yürütülmesi sağlanır - Mevcut paket yöneticileri ise
libuvthread pool tabanlıdır; yani pratikte içeride bloklayan kod çalıştırarak kaynak israfına yol açar
Paket manifestlerinin ikili önbelleğe alınması
- npm gibi araçlar manifestleri JSON olarak önbelleğe alırken, Bun bir kez parse ettikten sonra sonucu ikili (
.npmdosyası) biçimine dönüştürerek saklar - Böylece string tekrarları ve parse ek yükü azaltılır; gerçek bellekte ise yalnızca offset hesaplamasıyla değerlere doğrudan erişilebilir (yeni nesne oluşturma, parse veya garbage collection gerekmez)
ETagveIf-None-Matchbaşlıklarıyla yalnızca değişiklikler kontrol edilir; gereksiz veri parse etmeden güncellik doğrulanabilir- Benchmark'ta Bun'un önbellekten yaptığı kurulum, npm'in fresh install işleminden bile daha hızlıdır
Tarball (sıkıştırılmış dosya) işleme performansı
- Tipik paket yöneticileri tarball'ı akış olarak alır ve tampon bellek yetmediğinde yeniden ayırma, kopyalama ve yeniden boyutlandırma işlemleri peş peşe yaşanır
- Bun ise tarball'ın tamamını aldıktan sonra açar; gzip'in son 4 baytından sıkıştırılmamış boyutu önceden öğrenip yalnızca bir kez bellek ayırır
libdeflategibi araçlarla hızlı açma sağlanır; gereksiz tekrar kopyalama ve boyut değiştirme işlemleri tamamen ortadan kaldırılır
Bağımlılık grafiği ve veri yapısı optimizasyonu
- Mevcut paket yöneticileri JavaScript nesneleri/işaretçileri tabanlı bağımlılık ağaçları oluşturur; bu da belleğin rastgele dağılmasına ve sık CPU cache miss oluşmasına yol açar (pointer chasing sorunu)
- Bun, Structure of Arrays (SoA) desenini uygulayarak tüm paketleri, string'leri ve bağımlılıkları büyük ve ardışık bellek bloklarında saklar
- Offset/uzunluk tabanlı erişim sayesinde CPU, birden fazla paketi tek seferde cache line düzeyinde okuyabilir (cache dostu yapı)
- lockfile da JSON/YAML yerine SoA desenine uygun biçimde, string tekrarları kaldırılmış ve sıralı bellek erişimi kolay olacak şekilde tutulur
- lockfile için ikili biçim (
bun.lockb) deneysel olarak sunuldu ancak Git ile ortak çalışma deneyimini kötüleştirdiği için daha okunabilir düz metin biçimine geçildi
İşletim sistemine göre dosya kopyalama optimizasyonu
macOS
clonefilekullanımı: tüm dizin, tek bir sistem çağrısıyla Copy-On-Write yöntemiyle çoğaltılır- Disk alanı tekrar kullanımını en aza indirir ve kurulum hızını en üst düzeye çıkarır
clonefilebaşarısız olursa yedek olarak dizin bazlı kopyalama, ardındancopyfilekullanılır
Linux
- Önce hardlink denenir: yeni dosya oluşturmak yerine mevcut dosya için yeni bir referans oluşturulur (disk verisi taşınmaz)
- Hardlink mümkün değilse Btrfs/XFS üzerinde
ioctl_ficloneile Copy-On-Write uygulanır - Ardından sırasıyla
copy_file_range,sendfileve son olarak normalcopyfileyöntemine geri düşülür
Genel değerlendirme
- Bun, sistem çağrılarını azaltma, ikili yapılar, işletim sistemi optimizasyonları ve veri yapısı iyileştirmeleri sayesinde paket yöneticilerinin geleneksel performans sınırlarını aşmıştır
- Bunun sonucunda yalnızca son derece hızlı kurulum değil, aynı zamanda daha iyi bellek ve CPU verimliliği de sağlanır
- Mevcut Node.js tabanlı yöneticilere kıyasla, ayrı bir runtime değişikliği gerektirmeden projelerde uygulanabilir (uyumluluk korunur)
- Gerçek büyük kod tabanlarında dakikalar süren kurulum işlemlerini milisaniyeler ila saniyeler seviyesine indirme deneyimi sunar
- Sistem, donanım ve işletim sistemi düzeyine göre uyarlanmış optimizasyonların güçlü bir örneği olarak incelenmeye ve referans alınmaya değerdir
1 yorum
Hacker News görüşleri
Kullandığım M4 Max MacBook’un 2009 itibarıyla TOP500 süper bilgisayarları arasında ilk 50’ye gireceği iddiasını doğrulamaya çalıştım
2009 TOP500 listesine girmek için 75 TFlop/s üzerinde performans gerekiyordu
M4 Max FP32’de 18.4 TFlop/s sunuyor, ancak TOP500 FP64 (LINPACK) kullanıyor
M2 benchmark’ına göre FP64, FP32’nin yaklaşık 1/4’ü seviyesinde, bu yüzden kabaca 9 TFlop/s beklenir
Bu seviyede 2009 TOP500 listesine girilemez
2009 TOP500 listesi referans alınabilir
Her bağlantı aynı anda birden fazla I/O işi yapıyorsa, bunu binlerce bağlantıyla çarpmak gerekir
Sunucuların toplam sürenin yaklaşık %95’ini I/O bekleyerek geçirdiğini duydum ama bu aslında tüm sunucu için değil, tekil thread bazında geçerli
Gerçek sunucularda CPU kullanımı çoğu zaman %70-80’e kadar çıkar (bunun üstünde tail latency hızla kötüleşir)
Tam yükte CPU %5 kullanıyorsa bu, paralel süreç eksikliği ya da bellek yetersizliği sorunu demektir
Teknik olarak küçük bir ayrıntı ama bu tür hatalar yazının güvenilirliğini azaltabilir (bunu bir Bun hayranı olarak söylüyorum)
Bu sonucun biraz LLM’in ürettiği bir halüsinasyon gibi geldiğini düşünüyorum
Özellikle sonuç kısmı sanki LLM’den çıkmış gibi bir his veriyor
"Benchmark’ı yapılan paket yöneticilerinin yanlış değil, o döneme uygun çözümler olduğunu anladım"
"Bun’ın yaklaşımının devrimsel olmaktan çok, bugün neden yavaş olduğuna soğukkanlı biçimde bakmanın sonucu olduğu vurgulanıyor"
"Paket kurulumunun 25 kat hızlanması sihir değil; araçların modern donanıma göre yapılmasının doğal sonucu"
Konu karmaşık olmasına rağmen çok okunaklı ve sade anlatılmış olmasını çok beğendim
Hâlâ tutkulu insanların mevcut düzeni bozup zor problemlere meydan okuması hayranlık verici
Bilgisayar donanımı her ay gelişirken yazılımın daha da yavaşlaması anormal geliyor
Keşke herkes verimli kod yazma konusunda daha iyi olsa
Zig oldukça yeni bir dil ve onu gerçek dünyada ciddi biçimde kullanılırken görmek ilginç
bun’ı ilk kez denedim ve çok etkilendim
Yerleşik sunucu ve SQLite sayesinde sadece bun kurmak yetiyor, bu da geliştirmeyi çok daha rahat hâle getiriyor
Genelde sadece vanilla js kullanıyorum ve node ekosistemini pek sevmiyordum; bun’ı daha önce denemeliydim diye düşünüyorum
Bun’ı birkaç kez denedim ve kullanım deneyiminden çok memnun kaldım
Bana Node’dan daha iyi geldi
Ama her seferinde kritik bir probleme çarpıp sonunda Node’a geri döndüm
İlk başta crypto modülü Nodejs ile uyumlu değildi (şimdi düzeltilmiş), sonra da Playwright Bun’da çalışmadı
Bu aralar Node da yerleşik sunucu ve SQLite desteği sunuyor
Daha fazla özelliğe ihtiyaç varsa Hono da iyi bir alternatif
Yazıda Linux’un hard link’i ile MacOS’un clonefile’ının eşdeğer gibi anlatılan kısmını pek anlayamadım
Hard link durumunda bir kopyayı değiştirince tüm projelerdeki dosyalar beklenmedik şekilde değişmez mi diye merak ediyorum
Teknik olarak epey karmaşık bir açıklama olmasına rağmen gerçekten çok okunabilir ve keyifli yazılmış olmasına hayran kaldım
İşlerinin ve videolarının çoğunu gördüm; derinlemesine hazırlandığı hissediliyor
Vaktiniz varsa makalelerini ve YouTube içeriklerini kesinlikle tavsiye ederim
Son dönemde muhtemelen mevcut işi nedeniyle daha az aktif gibi görünüyor
Binary Manifest Caching bölümünde "npm (cached)" için benchmark süresi eksik gibi görünüyor
Sadece bun, bun (cached) ve npm var; özet istatistikler de tam tutmuyor gibi
Bu gönderinin üslubunu çok sevdim
io_uring’in önemini anlatmak için bu yazı çok iyi bir örnek olarak yeniden konumlandırılabilir gibi duruyor
Zig’in yakın tarihli v0.15 io güncellemesinin Bun performansına ek fayda sağlayıp sağlamayacağını merak ediyorum
1 yıldan uzun süredir bun’dan beklenti içindeyim
2025’in bun’ın yaygınlaşma yılı olacağını düşünmüştüm ama şaşırtıcı biçimde hâlâ o kadar popüler değil
GitHub’daki en üst 100 bin repo içinde, 2025 itibarıyla yeni repolarda npm 35 kat, pnpm ise 11 kat daha fazla kullanılıyor
Deno da beklediğim kadar popüler değil
Sebebi ne acaba diye merak ediyorum
Bunun nedeni, runtime tarafında uyumluluk sağlamanın paket yöneticisine göre daha zor olması mı?
bun’ı deneyip benimsemeyenlerin görüşlerini duymak isterim
İlgili istatistikler
İlgili HN yorumu
Hem Bun’ı hem Deno’yu sevmek istediğim için birkaç kez denedim ama sonunda belirleyici bir kusurla karşılaştığım için kullanmayı bıraktım
Bun’da son dönemde yaşadığım en büyük sorun stream’lerin erken kapanmasıydı
İlgili issue bağlantısı
Deno’da ise bellek sızıntısı problemiyle karşılaştım
İlgili issue bağlantısı
Sonuçta Node ekosisteminin Bun/Deno’nun avantajlarını önce kendi içine alacağını düşünüyorum
Bun, yeni venture capital finansmanı almış, doğrulanmış açık kaynak ana akım ürün Node ile rekabet eden yeni bir oyuncu
Lock-in teşviki var ve sonuçta Node’dan temelde çok da farklı değil
Stratejik üstünlüğü net değil ve Node ile yapılamayan gerçekten yeni bir şey sunmuyor
Ciddi biçimde kullanıldığı bir örnek görmedim; sadece hafif kullanım örnekleri gördüm
Issue tracker’a bakınca, Zig dili çok güvenli olmadığından mı bilmiyorum ama crash’ler sık yaşanıyor gibi görünüyor
Ben Node’da kalacağım
Ben de başkalarının görüşlerini merak ediyorum
Bana göre Node, proje olarak olgun, demokratik ve topluluk güdümlü hissettiriyor
Bunu io.js fork krizini iyi atlatmış olmasına bağlıyorum
Buna karşılık bun ve deno, ikisi de VC destekli projeler olduğu için demokratik ve topluluk odaklı gibi gelmiyor
Ben sıkı bir Bun hayranıyım
Mümkün olan her projede Bun kullanıyorum, çeşitli tek seferlik script’leri de Bun/TS ile yazıyorum
Ama az sayıda da olsa endişe verici issue’lar olduğu için production dağıtıma hâlâ çekiniyorum
Örneğin basit bir Express web sunucusunu Docker içinde çalıştırdığımda bun ile başlatınca takılı kalıyordu
Sadece node’a geçince normal çalışıyordu
1 yıl önce de Bun + Prisma kombinasyonunda sunucunun bellek sızıntısı yüzünden çökmesi sorunu vardı (muhtemelen şimdi düzelmiştir diye tahmin ediyorum)
Buna rağmen Bun’ı o kadar seviyorum ki bu eksileri tolere etsem bile genel olarak geliştirme süresini azaltıyor
Transpile, modüller, workspace’ler gibi alanlarda sağladığı kolaylık çok büyük
Henüz npm kadar yaygınlaşmamış olmasını da gayet anlaşılır buluyorum
Bu yazıyı okumak çok keyifliydi
Yazılım geliştirmede bilgisayar bilimi ilkelerinin gerçekte ne kadar önemli olduğunu çok iyi gösteren bir örnek
Big O, zaman/mekân yerelliği, algoritma karmaşıklığı, user/kernel space, dosya sistemi, copy-on-write gibi kavramlar
Bu tür düşük seviye paket geliştirmede, CS programında öğrenilen neredeyse her kavram pratikte kullanılıyor
CS; hesaplama ve teoriyle ilgilenir (programlama dilleri, algoritmalar, kriptografi, makine öğrenimi vb.)
SE ise ölçeklenebilir ve güvenilir yazılımlar kurmak için mühendislik ilkelerini uygular
Sıkıştırılmış dosyanın tamamı okunana kadar bekleyip sonra açmanın neden avantajlı olduğunu tam anlayamadım
İndirme bitmeden sıkıştırmayı açmaya başlamanın, belleğin yeniden kopyalanma sayısını artırma dezavantajına rağmen daha faydalı olacağını tahmin ediyorum