Perry vs Bun
Bun é um runtime tudo-em-um de JavaScript/TypeScript, bundler, gerenciador de pacotes e test runner que também consegue produzir executáveis de arquivo único empacotando seu runtime junto com o seu código. Perry segue um caminho diferente: compila TypeScript diretamente para código de máquina nativo via LLVM — sem motor JavaScript no binário, sem runtime, apenas um pequeno executável nativo. Bun e Perry se sobrepõem na saída TS-para-binário, mas discordam sobre se um motor JavaScript deve estar nesse binário.
O que é Bun?
Bun é um toolkit rápido e tudo-em-um de JavaScript e TypeScript construído em Zig. Ele executa código-fonte `.ts` diretamente (sem etapa de pré-compilação), usa JavaScriptCore como motor JS e inclui bundler, gerenciador de pacotes e test runner. `bun build --compile` empacota o runtime do Bun junto com sua aplicação em um único executável. Bun tem como alvo Linux, macOS e Windows em x64 e arm64.
O que é Perry?
Perry é um compilador nativo de TypeScript escrito em Rust. Ele compila TypeScript diretamente para código de máquina nativo via LLVM — sem motor JavaScript, sem runtime, sem JIT. A saída é um único binário (cerca de 330 KB para um hello world; ~48 MB para uma aplicação completa com stdlib, como um servidor Fastify). Perry tem como alvo 10 plataformas, incluindo macOS, iOS, iPadOS, Android, Linux, Windows, watchOS, tvOS, WebAssembly e Web.
Lado a lado
| Funcionalidade | Perry | Bun |
|---|---|---|
| Saída | Código de máquina nativo (LLVM) | Seu código + runtime do Bun empacotados em um binário |
| Motor JavaScript no binário | Nenhum por padrão; V8 opcional com --enable-js-runtime (+~15 MB) | JavaScriptCore, sempre |
| Tamanho de binário hello-world | ~330 KB | ~50–100 MB (inclui o runtime do Bun) |
| JIT | Não (compilado AOT) | Sim (JIT do JavaScriptCore) |
| Alvos mobile (iOS, Android) | Sim — UI nativa via UIKit/JNI | Não |
| Alvos relógio / TV | watchOS, tvOS, Wear OS | Não |
| Widgets de UI nativos | 25+ via AppKit, UIKit, GTK4, Win32, JNI | Não (foco em servidor/CLI) |
| Ecossistema npm | Pacotes TS/JS puros podem compilar nativamente; outros via V8 opcional | npm completo, compatível com Node |
| Estabilidade | Pré-1.0 (alfa) | Estável (1.x) |
| Construído em | Rust | Zig |
Onde o Perry ganha
- +Binários menores — um hello world em Perry tem ~330 KB; um hello world com `bun --compile` inclui o runtime do Bun e fica na casa das dezenas de megabytes.
- +Sem custo de motor JavaScript. Binários compilados pelo Perry não carregam interpretador nem JIT — seu TypeScript é o executável.
- +Mobile, relógio e TV. Perry compila para iOS, iPadOS, Android, watchOS, tvOS e WebAssembly. Bun é apenas servidor/desktop.
- +UI nativa. O módulo perry/ui do Perry compila para widgets reais da plataforma (AppKit no macOS, UIKit no iOS, GTK4 no Linux, Win32 no Windows, JNI no Android). Bun não tem proposta de UI.
- +Mais rápido na maioria dos microbenchmarks de computação medidos sob condições equivalentes em M1 Max (RUNS=11, v0.5.279, 2026-04-25): fibonacci 318 ms vs Bun 589 ms; object_create 1 ms vs 6 ms; nested_loops 18 ms vs 21 ms. Veja perry/benchmarks para a tabela completa.
- +Mais rápido em validate-and-roundtrip de JSON no pelotão de tipagem dinâmica: a tape JSON preguiçosa do Perry alcança mediana de 75 ms vs 259 ms do Bun na mesma carga de 10 mil registros.
Onde o Bun ganha
- +Runtime maduro e estável com lançamentos 1.x. Perry está pré-1.0.
- +Mais rápido em parse-and-iterate de JSON (onde cada valor é tocado): Bun 254 ms vs Perry 466 ms de mediana na mesma carga — a tape preguiçosa do Perry não consegue tomar atalhos quando a iteração é forçada.
- +Ecossistema npm completo e compatível com Node imediatamente. Perry roda um subconjunto nativamente e recorre ao V8 embutido opcional para o restante.
- +Test runner, bundler e gerenciador de pacotes integrados. Perry é um compilador — ferramentas adjacentes são separadas.
- +Desempenho com JIT aquecido pode superar AOT em código pesado em iteração com loops internos quentes; Perry não tem JIT.
- +Empatado com o Perry dentro do ruído execução-a-execução em `loop_data_dependent` (232 ms vs 235 ms) — o kernel de f64 genuinamente não-redutível, em que nenhum dos compiladores consegue reordenar. Fonte: perry/benchmarks RUNS=11.
Quando escolher Perry
Escolha o Perry quando o tamanho do binário importa (distribuição mobile, contextos embarcados, cold starts rápidos), quando você quer entregar para mobile/relógio/TV a partir de um único código TypeScript, quando você quer widgets de UI nativos ou quando você não quer um motor JavaScript no seu artefato entregue.
Quando escolher Bun
Escolha o Bun quando você precisa de um runtime estável e maduro hoje, quando compatibilidade total com npm é inegociável, quando você quer uma única ferramenta para runtime + bundler + gerenciador de pacotes + test runner, ou quando o desempenho com JIT aquecido em cargas de longa duração importa mais do que tamanho de cold start.
Veredito
Bun e Perry permitem entregar um programa TypeScript como um único binário, mas respondem perguntas diferentes. O binário do Bun contém o runtime do Bun e é otimizado para cargas de backend/CLI onde JIT e compatibilidade total com Node ganham. O binário do Perry não contém motor JS e é otimizado para tamanho, cold start, mobile e UI nativa. Se você está entregando um servidor, Bun é mais comprovado hoje. Se você está entregando uma aplicação nativa ou se importa com tamanho de binário, Perry foi feito para esse caso.