Bun em Rust: O Que a Reescrita Ensina para Quem Usa Zig

Bun sempre foi um dos exemplos mais fortes de Zig em produção: um runtime JavaScript de alta performance, com bundler, test runner, package manager e compatibilidade ampla com o ecossistema Node.js. Por isso, a abertura do pull request “Rewrite Bun in Rust”, por Jarred Sumner, chamou tanta atenção.

Segundo o próprio PR, a mudança ainda tem trabalho de otimização e limpeza antes de chegar a uma versão não-canary. Mesmo assim, a proposta é grande o bastante para merecer análise: Bun, um dos cases mais conhecidos de Zig, está testando uma migração ampla para Rust em busca de ferramentas mais fortes para encontrar e prevenir bugs de memória.

Isso não significa que “Zig perdeu” ou que “Rust ganhou” de forma simplista. A leitura mais útil para quem programa em Zig é outra: projetos grandes têm pressões diferentes de projetos pequenos, e a linguagem escolhida precisa combinar com o tipo de bug, a equipe, a base de testes e o ritmo de manutenção.

O que aconteceu com Bun?

O PR #30412 no repositório do Bun propõe uma reescrita de grande parte da base em Rust. A descrição do PR afirma alguns pontos importantes:

  • A suíte de testes pré-existente passa em todas as plataformas.
  • A mudança corrige alguns vazamentos de memória e testes instáveis.
  • O binário fica menor em alguns cenários, com redução citada entre 3 MB e 8 MB.
  • Os benchmarks ficam entre neutros e mais rápidos.
  • A arquitetura e as estruturas de dados continuam em grande parte iguais.
  • O projeto não passa a usar “async Rust” como centro da arquitetura.

A motivação declarada é clara: Bun vinha pagando um custo alto com vazamentos de memória e crashes difíceis de diagnosticar. Rust oferece ferramentas de compilador e ecossistema que ajudam a capturar esse tipo de problema antes do runtime.

A newsletter Bytes resumiu o episódio como uma decisão ousada: uma mudança gigantesca, feita rapidamente, em um projeto fundamental para muitos desenvolvedores JavaScript. A reação forte é compreensível. Quando um runtime com ambição de substituir Node.js mexe na linguagem interna, isso afeta a percepção de estabilidade, manutenção e confiança técnica.

Por que isso importa para a comunidade Zig?

Porque Bun era, e ainda é, um argumento de adoção para Zig. Nosso artigo Como o Bun Foi Construído com Zig explica por que o projeto escolheu Zig originalmente: performance, integração com C, controle de alocação, compilação rápida e simplicidade de sistemas.

Se um projeto desse tamanho considera trocar parte relevante da base para Rust, a comunidade Zig precisa olhar com maturidade. Não adianta responder com torcida. A pergunta certa é: que dor técnica apareceu em produção?

Pelo PR, a dor parece estar menos em performance bruta e mais em depuração, vazamentos e previsibilidade de memória em uma base enorme. Zig oferece ferramentas importantes para isso, como allocators explícitos, defer, errdefer, builds de debug com checagens e uma cultura de controle explícito. Mas Rust adiciona outro tipo de garantia: ownership e borrowing verificados pelo compilador.

Em bases grandes, com muitas contribuições e múltiplos subsistemas, esse tipo de garantia pode reduzir a superfície de bugs que chegam aos testes e aos usuários.

Zig e Rust resolvem problemas diferentes

A comparação entre Zig e Rust costuma virar guerra de slogans, mas a diferença real é mais prática.

Zig aposta em simplicidade explícita. Você vê o alocador, vê onde a memória entra e sai, vê o erro como parte do tipo, e evita uma camada grande de abstração. Isso é excelente para programadores que querem controle direto e para projetos onde a equipe consegue manter disciplina manual com boas práticas.

Rust aposta em fazer o compilador recusar classes inteiras de erro. O custo é uma linguagem mais complexa, com lifetimes, traits, borrow checker e uma curva de aprendizado mais pesada. A recompensa é que muitos erros de uso de memória nem chegam a compilar.

Para um projeto como Bun, os dois lados importam:

CritérioZigRust
Controle de baixo nívelMuito forteMuito forte
Integração com CSimples e diretaBoa, mas mais cerimonial
Segurança de memória em compilaçãoParcial/indiretaForte
Ergonomia para depurar vazamentosDepende de allocators e testesApoiada pelo modelo de ownership
Curva de aprendizadoMenor para quem vem de CMaior
Ecossistema de cratesMenorMuito maior
Complexidade da linguagemBaixaAlta

A decisão não é “qual linguagem é melhor”. É “qual conjunto de trade-offs reduz mais risco para este projeto”.

A importância da suíte de testes

Um detalhe central do PR é que Bun já tinha uma suíte de testes extensa. Isso muda tudo.

Reescrever um projeto grande sem testes é uma aposta perigosa. Reescrever com testes de compatibilidade, regressão e comportamento observável é outra história. A linguagem pode mudar por baixo, mas a pergunta principal continua sendo: o runtime se comporta igual para o usuário?

Esse é um ponto importante para qualquer projeto Zig. Se você quer manter liberdade para refatorar internamente, mudar alocadores, trocar subsistemas ou portar componentes, invista em testes que validem comportamento, não detalhes de implementação.

No caso do Bun, a compatibilidade com Node.js obriga uma disciplina de testes que favorece esse tipo de migração. Em projetos menores, essa rede de segurança normalmente não existe. Por isso, copiar a ousadia do Bun sem copiar a infraestrutura de testes seria um erro.

O que Zig pode aprender com o episódio

A primeira lição é que performance não basta. Zig já entrega performance excelente, compilação cruzada forte e uma experiência muito boa para sistemas. Mas projetos de larga escala também precisam de ferramentas para manutenção diária: análise de memória, rastreamento de vazamentos, diagnósticos claros, ergonomia para times grandes e integração contínua confiável.

A segunda lição é que allocators explícitos são uma vantagem, mas não eliminam disciplina. Em Zig, o design força você a pensar em memória. Isso é ótimo. Mas pensar não é o mesmo que provar. Testes, ferramentas de leak detection, revisão cuidadosa e padrões de arquitetura continuam sendo obrigatórios.

A terceira lição é que estabilidade de ecossistema pesa. Rust tem Cargo, crates.io, tooling maduro e muita experiência acumulada em produção para segurança de memória. Zig está evoluindo rápido, mas ainda é pré-1.0. Para alguns projetos, esse dinamismo é aceitável. Para outros, vira custo de manutenção.

Nada disso diminui Zig. Pelo contrário: mostra onde a linguagem precisa continuar amadurecendo para competir em bases cada vez maiores.

O que isso não significa

Não significa que Zig deixou de ser adequado para produção. TigerBeetle, Ghostty, ferramentas de build, compiladores e sistemas embarcados continuam sendo ótimos exemplos de onde Zig faz sentido.

Também não significa que todo projeto Zig deveria migrar para Rust. A maior parte dos projetos não tem a escala, a superfície de compatibilidade nem a pressão operacional do Bun. Em muitos casos, a simplicidade de Zig continua sendo uma vantagem enorme.

E não significa que Rust seja automaticamente a melhor escolha para runtimes JavaScript. Deno usa Rust, Bun nasceu em Zig, Node.js usa C++ e todos têm trade-offs próprios. A linguagem interna é só uma parte da história; arquitetura, testes, equipe e ecossistema contam tanto quanto.

Como avaliar Zig para novos projetos depois disso?

Se você está escolhendo Zig para um projeto novo, use perguntas concretas:

  1. A equipe entende gerenciamento explícito de memória?
  2. O projeto se beneficia de compilação cruzada simples?
  3. A integração com C é central?
  4. A base será pequena/média ou uma plataforma enorme com muitos contribuidores?
  5. O risco principal é performance, tamanho de binário e controle, ou bugs de memória difíceis de rastrear?
  6. Você tem testes fortes o bastante para refatorações grandes?
  7. A maturidade do ecossistema é suficiente para suas dependências?

Se as respostas apontam para controle explícito, baixa dependência externa, integração com C e performance previsível, Zig continua excelente. Se o risco dominante é segurança de memória em uma base grande com muitos autores, vale estudar Rust com seriedade.

Para uma comparação mais ampla, veja também nosso guia Zig vs Rust. E, se você quer acompanhar a perspectiva do outro ecossistema em português, vale visitar Rust Lang Brasil.

Conclusão

A reescrita experimental do Bun em Rust é um sinal importante, mas não é uma sentença contra Zig. É um lembrete de que linguagens são ferramentas, e ferramentas precisam ser avaliadas pelo tipo de problema que reduzem.

Zig continua sendo uma das linguagens mais interessantes para programação de sistemas: simples, explícita, rápida e muito boa para quem quer controle real. Rust continua sendo a referência quando a prioridade é empurrar segurança de memória para o compilador.

O episódio do Bun mostra que a próxima fase da programação de sistemas não será decidida por slogans. Será decidida por projetos reais, bugs reais, testes reais e manutenção real.

Para quem programa em Zig, a melhor resposta não é defensiva. É técnica: entender o trade-off, fortalecer testes, usar allocators com disciplina, melhorar tooling e continuar construindo software que prove o valor da linguagem em produção.

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.