Um binário de 100 megas para um CLI

A Anthropic acabou de anunciar que o Claude Code já está disponível como native build. Traduzindo: um executável binário que você pode instalar com um curl e que não precisa do Node.js.

Soa bem, né? Um comando, sem dependências, auto-updates em background. O sonho de qualquer ferramenta CLI.

Mas tem um detalhe: o binário pesa 100MB.

Para colocar em perspectiva, o binário do git pesa uns 3MB. O do curl menos de 1MB. Até o Go, que tem fama de gerar binários pesados, raramente passa dos 15-20MB.

Que diabos tem dentro desses 100 megas?

Não é Rust, é Bun fantasiado de executável

Quando vi o anúncio, meu primeiro pensamento foi: “Reescreveram tudo em Rust”. Faz sentido, né? Se você quer um binário nativo, rápido e sem runtime, Rust é a opção óbvia.

Pois é, não é isso.

Claude Code continua sendo TypeScript. O que fizeram foi usar bun build --compile para empacotá-lo como executável.

Como funciona bun build --compile

O comando mágico é este:

1
bun build ./src/index.ts --compile --outfile claude

O que faz exatamente? Três coisas:

1. Bundling

Primeiro, o Bun atua como bundler. Pega seu arquivo de entrada (index.ts), resolve todos os import, e gera um único arquivo JavaScript com todo o código concatenado. Inclui suas dependências do node_modules, resolve tree-shaking para eliminar código morto, e minifica o resultado.

Até aqui, nada diferente do que fazem esbuild ou webpack.

2. Embedding

Aqui vem o interessante. O Bun pega esse bundle de JavaScript e incorpora dentro de um executável junto com o runtime completo do Bun.

O executável resultante tem esta estrutura (simplificada):

┌─────────────────────────────────┐
│   Runtime do Bun (~95MB)        │
│   ├── JavaScriptCore engine     │
│   ├── APIs nativas (fs, http)   │
│   ├── Zig runtime               │
│   └── libc estática             │
├─────────────────────────────────┤
│   Seu código bundleado (~5MB)   │
│   └── JavaScript minificado     │
└─────────────────────────────────┘

Quando você executa o binário, o runtime do Bun extrai o código JavaScript de si mesmo e o executa. É como um arquivo ZIP auto-extraível, mas para código.

3. Cross-compilation

O Bun pode gerar binários para outras plataformas:

1
2
3
bun build ./src/index.ts --compile --target=bun-linux-x64 --outfile claude-linux
bun build ./src/index.ts --compile --target=bun-darwin-arm64 --outfile claude-mac
bun build ./src/index.ts --compile --target=bun-windows-x64 --outfile claude.exe

Você não precisa ter Linux para gerar um binário do Linux. O Bun inclui os runtimes pré-compilados para cada plataforma.

JavaScriptCore vs V8

O Node.js usa V8, o motor JavaScript do Chrome. O Bun usa JavaScriptCore (JSC), o motor do Safari.

Por que isso importa? Porque são feras diferentes:

AspectoV8 (Node)JavaScriptCore (Bun)
Tempo de inicialização~50ms~5ms
Pico de performanceMuito altoAlto
Uso de memóriaMaiorMenor
JIT tiers2 (Ignition → TurboFan)4 (LLInt → Baseline → DFG → FTL)

O JSC tem uma inicialização mais rápida porque tem mais tiers de compilação JIT. Começa interpretando código muito rápido (LLInt) e vai otimizando em background enquanto executa. O V8, por sua vez, precisa fazer mais trabalho inicial antes de começar a executar.

Para um CLI que inicia, faz algo, e termina, esses 45ms de diferença na inicialização importam. Para um servidor que roda por horas, importa menos.

Por que Zig (e não Rust, nem C++)

O Bun está escrito principalmente em Zig, com um pouco de C++ para as partes que interagem com o JavaScriptCore.

Jarred Sumner, o criador do Bun, escolheu Zig por várias razões:

  1. Interoperabilidade com C: Zig pode chamar código C sem overhead nem FFI. JavaScriptCore está escrito em C++, e o Zig pode linkar com ele diretamente.

  2. Controle de memória sem garbage collector: Como Rust, mas com sintaxe mais simples e sem o borrow checker que quebra suas pernas.

  3. Compilação cruzada trivial: Zig pode compilar para qualquer plataforma a partir de qualquer plataforma. Você não precisa de uma máquina Linux para compilar para Linux.

  4. Binários pequenos (relativamente): Um “Hello World” em Zig pesa ~5KB. Em Go, ~2MB. Em Rust, ~300KB.

O resultado é um runtime que inicia rápido, usa pouca memória, e pode ser distribuído como um único binário estático. Exatamente o que você precisa para isso.

O que NÃO é

Para ficar claro: isso não é compilação AOT (Ahead-of-Time) como faz o GraalVM com Java ou WASM.

Seu código TypeScript não se converte em instruções de CPU. Continua sendo interpretado pelo JavaScriptCore em tempo de execução. A única coisa que muda é que o interpretador vem empacotado junto com o código.

É o mesmo truque que fazem:

  • pkg para Node.js
  • PyInstaller para Python
  • electron-builder para apps Electron

Não é mágica. É colocar o runtime e o código no mesmo pacote. Por isso pesa 100MB — a maior parte é JavaScriptCore e as APIs do Bun, não o código do Claude Code.

O que a Anthropic ganha?

Aqui está o ponto. Porque essa mudança não é por você.

Menos tickets de suporte

Sabe quantos problemas o npm dá? Permissões quebradas, cache corrompido, conflitos de versões do Node, PATH mal configurado, node_modules de 800MB que somem misteriosamente…

Cada um desses problemas é um ticket de suporte. Cada ticket de suporte é dinheiro e tempo. Multiplique pelos milhões de usuários do Claude Code e você entenderá por que a Anthropic decidiu eliminar o npm da equação.

Auto-updates sem fricção

Com npm, atualizar o Claude Code requer que o usuário execute npm update -g @anthropic/claude-code. Alguns fazem. Muitos não.

Com o native build, as atualizações acontecem automaticamente em background. A Anthropic tem controle total sobre qual versão você está executando. Para uma empresa que itera rápido e corrige bugs constantemente, isso é ouro.

Ambiente controlado

Quando chega um bug report, a primeira coisa que você pergunta é: “Qual versão do Node você tem? Qual versão do npm? Qual sistema operacional?”. Com o native build, tudo isso desaparece. O ambiente de execução é o mesmo para todos.

Bugs mais reproduzíveis = bugs mais fáceis de corrigir.

E o que o usuário ganha?

Se você não tem Node.js instalado

Melhoria clara. Antes você precisava:

  1. Instalar Node.js
  2. Configurar o PATH (se não foi feito automaticamente)
  3. Instalar npm (vem com Node, mas às vezes tem que atualizar)
  4. Executar npm install -g @anthropic/claude-code
  5. Rezar para não haver conflitos

Agora você precisa:

1
curl -fsSL https://claude.ai/install.sh | sh

Para alguém que não é desenvolvedor — um product manager, um escritor, um designer — a diferença é abissal.

Se você já tem Node.js

Honestamente, você ganha pouco. Talvez se livre de algum problema ocasional do npm. Os auto-updates são convenientes. O syntax highlighting nativo que só vem no native build é um nice-to-have.

Mas se já tinha o Claude Code funcionando com npm, a mudança é basicamente lateral. Você não vai notar diferença no dia a dia.

Os 100MB em perspectiva

Sei que soa como barbaridade. 100MB para um CLI. Nossos avós programavam com 4KB de RAM e aqui estamos baixando 100 megas para executar comandos.

Mas vamos ser realistas:

  • VS Code pesa ~300MB
  • Slack ~500MB
  • O SDK do iOS ~30GB
  • Um projeto médio de Node.js tem um node_modules de 500MB+

E meu favorito: macOS Sequoia inclui 45GB de papéis de parede.

Quarenta e cinco gigabytes. De wallpapers. Vídeos em 4K de águas-vivas flutuando, ondas quebrando, e a aurora boreal para que seu Mac tenha uma proteção de tela bonita. São 450 vezes o tamanho do Claude Code. Para. Papéis. De. Parede.

Claude Code te dá um assistente de IA que pode escrever código, executar comandos, e gerenciar projetos inteiros. Os papéis de parede da Apple te dão… águas-vivas.

Em 2026, com fibra de 1Gbps e SSDs de 1TB como padrão, 100MB é ruído estatístico. Você baixa em segundos, salva e esquece.

É elegante? Não. Importa na prática? Também não. E certamente importa menos que as malditas águas-vivas.

Você deveria migrar?

Se tem a versão npm e funciona bem, não há pressa. Pode migrar executando claude install da versão npm.

Se está instalando o Claude Code pela primeira vez, use o native build. É a opção recomendada e a que menos problemas vai te dar.

Se você é daqueles que se incomodam em ter um binário de 100MB ocupando espaço, pode continuar com npm. A Anthropic diz que vai manter ambas as opções, embora esteja claro qual é a aposta do futuro.

O padrão que se repete

Isso não é novidade. É o mesmo padrão que vemos repetidas vezes no software:

  1. Você começa com dependências compartilhadas (DLLs, bibliotecas do sistema, npm packages)
  2. Se depara com problemas de compatibilidade, versões, e distribuição
  3. Acaba empacotando tudo junto em um blob pesado que simplesmente funciona

Docker fez a mesma coisa. Electron fez a mesma coisa. Bun está fazendo a mesma coisa.

É a solução mais elegante? Não. É a que menos problemas dá? Quase sempre sim.

Às vezes a engenharia não é sobre encontrar a solução mais bonita, mas a que gera menos tickets de suporte. E a Anthropic, com seus bilhões de receita e milhões de usuários, sabe disso melhor que ninguém.


Relacionados: