Perry vs Bun
Bun è un runtime JavaScript/TypeScript all-in-one, bundler, package manager e test runner che può anche produrre eseguibili a singolo file raggruppando il proprio runtime con il tuo codice. Perry sceglie un percorso diverso: compila TypeScript direttamente in codice macchina nativo tramite LLVM — nessun motore JavaScript nel binario, nessun runtime, solo un piccolo eseguibile nativo. Bun e Perry si sovrappongono sull'output da TS a binario ma sono in disaccordo sul fatto che un motore JavaScript debba trovarsi in quel binario.
Cos'è Bun?
Bun è un toolkit JavaScript e TypeScript veloce e all-in-one costruito in Zig. Esegue i sorgenti `.ts` direttamente (nessuno step di precompilazione), usa JavaScriptCore come motore JS e include un bundler, un package manager e un test runner. `bun build --compile` raggruppa il runtime di Bun insieme alla tua applicazione in un singolo eseguibile. Bun supporta Linux, macOS e Windows su x64 e arm64.
Cos'è Perry?
Perry è un compilatore TypeScript nativo scritto in Rust. Compila TypeScript direttamente in codice macchina nativo tramite LLVM — nessun motore JavaScript, nessun runtime, nessun JIT. L'output è un singolo binario (circa 330 KB per un hello world; ~48 MB per un'app completa con stdlib come un server Fastify). Perry supporta 10 piattaforme tra cui macOS, iOS, iPadOS, Android, Linux, Windows, watchOS, tvOS, WebAssembly e il Web.
Fianco a fianco
| Caratteristica | Perry | Bun |
|---|---|---|
| Output | Codice macchina nativo (LLVM) | Il tuo codice + runtime Bun raggruppati in un binario |
| Motore JavaScript nel binario | Nessuno di default; V8 opzionale con --enable-js-runtime (+~15 MB) | JavaScriptCore, sempre |
| Dimensione del binario hello-world | ~330 KB | ~50–100 MB (include il runtime Bun) |
| JIT | No (compilato AOT) | Sì (JIT di JavaScriptCore) |
| Target mobile (iOS, Android) | Sì — UI nativa via UIKit/JNI | No |
| Target Watch / TV | watchOS, tvOS, Wear OS | No |
| Widget UI nativi | 25+ via AppKit, UIKit, GTK4, Win32, JNI | No (focalizzato su server/CLI) |
| Ecosistema npm | I pacchetti pure-TS/JS possono compilare nativamente; gli altri tramite V8 opzionale | npm completo compatibile con Node |
| Stabilità | Pre-1.0 (alpha) | Stabile (1.x) |
| Costruito in | Rust | Zig |
Dove vince Perry
- +Binari più piccoli — un hello world Perry è ~330 KB; un hello world Bun --compile include il runtime Bun e si attesta su decine di megabyte.
- +Nessun costo del motore JavaScript. I binari compilati da Perry non trasportano un interprete o un JIT — il tuo TypeScript è l'eseguibile.
- +Mobile, watch e TV. Perry compila per iOS, iPadOS, Android, watchOS, tvOS e WebAssembly. Bun è solo server/desktop.
- +UI nativa. Il modulo perry/ui di Perry compila in widget reali della piattaforma (AppKit su macOS, UIKit su iOS, GTK4 su Linux, Win32 su Windows, JNI su Android). Bun non ha alcuna proposta UI.
- +Più veloce sulla maggior parte dei microbenchmark di calcolo misurati in condizioni paragonabili su M1 Max (RUNS=11, v0.5.279, 25-04-2026): fibonacci 318 ms vs Bun 589 ms; object_create 1 ms vs 6 ms; nested_loops 18 ms vs 21 ms. Vedi perry/benchmarks per la tabella completa.
- +Più veloce su JSON validate-and-roundtrip nel gruppo a tipizzazione dinamica: la tape JSON lazy di Perry atterra a 75 ms di mediana vs i 259 ms di Bun sullo stesso carico di lavoro da 10k record.
Dove vince Bun
- +Runtime maturo e stabile con release 1.x. Perry è pre-1.0.
- +Più veloce su JSON parse-and-iterate (dove ogni valore viene toccato): Bun 254 ms vs Perry 466 ms di mediana sullo stesso carico — la tape lazy di Perry non può prendere scorciatoie quando l'iterazione è forzata.
- +Ecosistema npm completo compatibile con Node out of the box. Perry esegue un sottoinsieme nativamente e ricade sul V8 embedded opzionale per il resto.
- +Test runner, bundler e package manager integrati. Perry è un compilatore — gli strumenti adiacenti sono separati.
- +Le prestazioni a JIT-warm possono superare l'AOT su codice iterazione-intensivo con loop interni hot; Perry non ha JIT.
- +Pari merito con Perry entro il rumore tra esecuzioni su `loop_data_dependent` (232 ms vs 235 ms) — il kernel f64 genuinamente non riducibile dove nessuno dei due compilatori può riordinare. Fonte: perry/benchmarks RUNS=11.
Quando scegliere Perry
Scegli Perry quando la dimensione del binario conta (distribuzione mobile, contesti embedded, avvii a freddo veloci), quando vuoi distribuire su mobile/watch/TV da un unico codice TypeScript, quando vuoi widget UI nativi o quando non vuoi affatto un motore JavaScript nel tuo artefatto distribuito.
Quando scegliere Bun
Scegli Bun quando hai bisogno di un runtime stabile e maturo oggi, quando la piena compatibilità con npm è non negoziabile, quando vuoi un singolo strumento per runtime + bundler + package manager + test runner, o quando le prestazioni a JIT-warm su carichi a lunga esecuzione contano più della dimensione di avvio a freddo.
Verdetto
Bun e Perry permettono entrambi di distribuire un programma TypeScript come singolo binario, ma rispondono a domande diverse. Il binario di Bun contiene il runtime Bun ed è ottimizzato per carichi backend/CLI dove vincono il JIT e la piena compatibilità con Node. Il binario di Perry non contiene alcun motore JS ed è ottimizzato per dimensione, avvio a freddo, mobile e UI nativa. Se stai distribuendo un server, Bun è più consolidato oggi. Se stai distribuendo un'app nativa o ti interessa la dimensione del binario, Perry è costruito per quel caso.