Compile TypeScript para um Binário

Um único comando transforma main.ts em um executável nativo standalone. Sem Node.js na máquina de destino, sem runtime empacotado, sem etapa de instalação para seus usuários.

terminal

$ perry compile main.ts

✓ Compiled executable: main (2.3 MB)

$ ./main

Hello, World!

Três coisas que as pessoas chamam de “compilar TypeScript”

Quando desenvolvedores pesquisam como compilar TypeScript para um binário, geralmente encontram três técnicas bem diferentes que compartilham uma palavra:

  • Transpilação. tsc, SWC e esbuild transformam TypeScript em JavaScript. A saída ainda precisa de Node.js, Bun ou um navegador para rodar. Nenhum binário está envolvido.
  • Runtime embutido. bun build --compile, deno compile e as Single Executable Applications (SEA) do Node.js concatenam seu JavaScript empacotado com uma cópia completa do runtime. Você obtém um único arquivo, mas o motor viaja junto dentro dele e seu código ainda é analisado e compilado via JIT toda vez que o processo inicia.
  • Compilação nativa ahead-of-time. É isso que o Perry faz. O TypeScript é analisado com SWC, os tipos são resolvidos, os generics são monomorfizados, e o LLVM emite código de máquina. O linker produz um executável normal — a mesma classe de artefato que um toolchain de Rust, Go ou C++ produz. Não há motor JavaScript algum no binário.

Como não há motor para inicializar nem nada para analisar na inicialização, um binário do Perry inicia em cerca de um milissegundo. O próprio pipeline é descrito com mais profundidade na página do compilador nativo de TypeScript e em detalhes internos do compilador.

Qual é o tamanho do binário?

O tamanho depende do que você importa, porque apenas o código que você realmente usa é compilado e vinculado:

  • Um hello world tem cerca de 330 KB.
  • Ferramentas de CLI típicas ficam em 2–5 MB.
  • Aplicações completas que vinculam frameworks grandes (Fastify, mysql2 e afins) ficam em cerca de 48 MB.

Para efeito de comparação: um executável Node SEA é uma cópia do próprio binário node, então ele começa em cerca de 88–118 MB dependendo da plataforma antes mesmo de adicionar seu código, e um hello world compilado com o Bun mede cerca de 60 MB no macOS arm64 e cerca de 100 MB no Linux x64, porque todo o runtime do Bun é embutido.

Perry vs bun build --compile vs Node SEA

Os três te dão um único arquivo que você pode entregar a alguém. Fora isso, são ferramentas muito diferentes, e cada uma é a resposta certa para alguém:

Perrybun build --compileNode SEA
O que produzCódigo de máquina compilado AOT (LLVM)JS empacotado + runtime do Bun embutidoCópia do binário node com seu script empacotado injetado
Modelo de execuçãoCódigo nativo, sem motor JSJIT (JavaScriptCore) em tempo de execuçãoJIT (V8) em tempo de execução
Tamanho do hello world~330 KB~60 MB (macOS arm64) a mais de ~100 MB (Linux/Windows)~88–118 MB (tamanho do binário node)
Inicialização~1 ms~10 ms~30 ms
Compilação cruzada10 alvos, incluindo Windows/macOS/iOS a partir do LinuxSim — Linux, Windows, macOS via --targetNão — em vez disso, copie um binário node específico da plataforma
Compatibilidade JS/npmCrescente: axios, zod v4, express, fastify, hono compilam nativamente; runtime V8 opcional para o restanteCompleta — é o próprio runtime do BunSemântica completa do Node; requer pré-empacotamento, apenas CommonJS no Node 24 LTS
StatusPré-1.0EstávelEstabilidade “em desenvolvimento ativo” no Node 24 LTS

Colocando as coisas com honestidade: se sua aplicação depende do ecossistema npm completo e você quer risco zero de compatibilidade, Bun e Node SEA rodam exatamente a semântica de motor contra a qual você já desenvolve — essa é a força deles, e o custo de tamanho pode não importar para o seu deployment. O Perry é uma troca diferente. Você ganha compilação ahead-of-time de verdade, binários pequenos e inicialização em milissegundos; em troca, você adota um compilador pré-1.0 cuja conformidade com JavaScript é medida e publicada (test262: String 79%, Array 72% na v0.5.1146) em vez de herdada do V8.

Comparações detalhadas: Perry vs Bun e Perry vs Deno. Para como os pacotes npm compilam, veja Pacotes npm reais e uma varredura de conformidade.

Comparação de desempenho

A compilação nativa oferece eficiência incomparável

MétricaPerryNode.jsBun
Tamanho do binário2-5 MB~80 MB~90 MB
Tempo de inicialização~1 ms~30 ms~10 ms
Dependências de runtimeNenhumaNode.jsBun
Overhead de memóriaMínimoV8 + GCJSC + GC

Resultados do benchmark: Até 18x mais rápido

Perry v0.5.279 vs Node.js v25 — mediana de RUNS=11, Apple M1 Max (menor é melhor)

accumulate
18x
object create
11x
json roundtrip
5.3x
loop overhead
4.5x
math intensive
3.6x
array read
3.3x
fibonacci
3.2x
array write
2.3x
loop data dependent
1.4x
nested loops
1.0x
Tamanho do binárioMenor é melhor
Perry
5 MB
Node.js
80 MB
Bun
90 MB

Compile seu primeiro binário hoje

Instale com Homebrew, APT ou winget — depois perry compile main.ts.