Como o Bun foi Construído com Zig: Case Study Completo

Como o Bun foi Construído com Zig: Case Study Completo

Bun é um dos projetos mais impressionantes escritos em Zig. Este runtime JavaScript, lançado em 2022, promete ser 3x mais rápido que Node.js e já acumula mais de 70.000 estrelas no GitHub. Mas o que torna Bun especial não é apenas a velocidade — é a escolha de Zig como linguagem principal.

Neste case study completo, vamos analisar:

  • Por que o criador do Bun escolheu Zig
  • Como Zig possibilitou a performance do Bun
  • A arquitetura técnica por trás do runtime
  • Desafios enfrentados e como foram resolvidos
  • Lições aplicáveis aos seus próprios projetos Zig

Sobre Bun: Bun é um runtime JavaScript completo, bundler, transpiler e gerenciador de pacotes. É escrito em Zig desde o início e se tornou provavelmente o projeto Zig mais famoso em produção.


Índice

  1. O Que é Bun?
  2. Por Que Zig? A Decisão do Criador
  3. Arquitetura do Bun
  4. Otimizações de Performance
  5. Desafios Técnicos e Soluções
  6. Comparativo: Bun vs Node.js vs Deno
  7. Projetos Similares em Zig
  8. Lições para Desenvolvedores Zig
  9. Recursos e Referências
  10. Próximos Passos

O Que é Bun?

Bun é um runtime JavaScript all-in-one criado por Jarred Sumner. Diferente de Node.js (C++) e Deno (Rust), Bun foi construído do zero em Zig.

Características Principais

FeatureDescrição
Runtime JSExecuta JavaScript e TypeScript nativamente
BundlerEmpacota aplicações web
TranspilerConverte TS/JSX/TSX em JS nativamente
Package ManagerSubstitui npm/yarn/pnpm
Test RunnerTestes integrados com Jest-like API
SQLiteBanco de dados embutido

Números Impressionantes

  • 70.000+ estrelas no GitHub
  • 3x mais rápido que Node.js em benchmarks
  • 4x mais rápido que Deno
  • Inicialização 2x mais rápida que Node.js
  • Bundle 20x mais rápido que webpack

Por Que Zig? A Decisão do Criador

Jarred Sumner, criador do Bun, teve acesso a qualquer linguagem. Por que escolheu Zig?

A Entrevista Original

Em uma entrevista para o blog do Zig, Jarred explicou:

“Eu queria uma linguagem que me desse controle total sobre memória e performance, mas que não fosse tão complexa quanto C++. Zig foi perfeito porque é simples como C, mas moderna e segura.”

Critérios de Seleção

CritérioC++RustGoZigNotas
Performance⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐Todas são rápidas
Controle de memóriaManualBorrow checkerGCAllocators explícitosZig: controle sem complexidade
Facilidade❌ Complexa⚠️ Curva íngreme✅ Fácil✅ SimplesZig = C moderno
Interop com CNativaVia FFIVia cgoNativaZig vence aqui
Build systemCMake/makeCargogo buildIntegradobuild.zig ideal
CompilaçãoLentaLentaRápidaMuito rápidaCrucial para iteração
Tamanho binárioGrandeGrandeGrandePequenoImportante para runtime

Por Que Não Rust?

Rust é a escolha óbvia para sistemas modernos. Por que Zig?

  1. Compilação mais rápida — Crucial para iteração no desenvolvimento
  2. Sem borrow checker — Menos complexidade para código que precisa de flexibilidade
  3. Interop com C nativa — Bun precisa integrar com muitas libs C (JavaScriptCore, libuv, etc.)
  4. Sintaxe mais simples — Mais fácil contribuir, menor barreira de entrada
  5. Allocators explícitos — Controle fino sobre onde e quando memória é alocada

Por Que Não Go?

Go é excelente para ferramentas CLI e servidores. Por que não Bun?

  1. Garbage collector — Inaceitável para runtime de baixa latência
  2. Controle limitado — Go abstrai demais para um projeto tão low-level
  3. Interop limitada — cgo é lento e complexo

Por Que Não C++?

C++ é o padrão para runtimes (V8, Node.js). Por que mudar?

  1. Complexidade — C++ é gigantesca e cheia de armadilhas
  2. Build system — CMake é doloroso; build.zig é trivial
  3. Compilação lenta — Template metaprogramming é lento
  4. Segurança — Zig evita classes de bugs comuns em C++

A Decisão Final

Jarred escolheu Zig porque oferecia:

  • Performance de C/C++
  • Simplicidade de Go
  • Segurança de Rust (em debug builds)
  • Interop nativa com C
  • Build system integrado
  • Compilação extremamente rápida

Arquitetura do Bun

Como Bun é organizado internamente? Vamos analisar a arquitetura de alto nível.

Visão Geral da Stack

┌─────────────────────────────────────┐
│  JavaScript/TypeScript/TSX          │  ← Código do usuário
├─────────────────────────────────────┤
│  Transpiler (Zig)                   │  ← TS → JS nativo
├─────────────────────────────────────┤
│  JavaScriptCore (C++)               │  ← Engine JS da Apple
├─────────────────────────────────────┤
│  Bun Runtime (Zig)                  │  ← I/O, event loop, APIs
├─────────────────────────────────────┤
│  Syscalls (Zig → C → Kernel)        │  ← Sistema operacional
└─────────────────────────────────────┘

Componentes Principais em Zig

1. HTTP Server

Bun implementa um servidor HTTP ultrarrápido em Zig:

// Simplificado — representação conceitual do código do Bun
const Server = struct {
    socket: std.net.Server,
    
    pub fn listen(self: *Server, port: u16) !void {
        const address = try std.net.Address.parseIp("0.0.0.0", port);
        self.socket = try address.listen(.{
            .reuse_address = true,
            .kernel_backlog = 1024,
        });
    }
    
    pub fn accept(self: *Server) !Connection {
        return try self.socket.accept();
    }
};

2. Transpiler TypeScript

Bun transpila TypeScript para JavaScript 20x mais rápido que alternatives:

  • Parser escrito em Zig
  • Otimizado para throughput
  • Sem allocations desnecessárias
  • SIMD para parsing de strings

3. Gerenciador de Pacotes

O package manager do Bun é escrito inteiramente em Zig:

  • Downloads paralelos
  • Cache eficiente
  • Instalação automática
  • Compatibilidade com npm

4. Bundler

Bundler empacota aplicações web:

  • Tree-shaking
  • Minificação
  • Code splitting
  • Target ES2022 por padrão

JavaScriptCore Integration

Bun usa JavaScriptCore (JSC), a engine JavaScript da Apple (WebKit), em vez de escrever sua própria engine. Isso foi uma decisão inteligente:

VantagemExplicação
MaturidadeJSC é usado em Safari há décadas
PerformanceJIT compiler otimizado
CompatibilidadePassa 95%+ dos testes web
FocoBun foca no runtime, não engine

A integração é feita via bindings C, e Zig facilita muito essa interop.


Otimizações de Performance

Como Zig possibilita a velocidade do Bun? Vamos analisar as técnicas específicas.

1. Zero-Cost Abstractions

Zig não adiciona overhead por abstrações:

// Struct em Zig: layout exatamente como definido
const Request = struct {
    method: []const u8,
    url: []const u8,
    headers: Headers,
};

// Sem padding extra, sem vtables, sem overhead
// Tamanho = exatamente o necessário

2. Allocators Especializados

Bun usa allocators customizados para diferentes padrões de uso:

// Exemplo conceitual do approach do Bun
const ResponseArena = struct {
    // Arena para respostas HTTP — aloca tudo de uma vez
    arena: std.heap.ArenaAllocator,
    
    pub fn init() ResponseArena {
        return .{
            .arena = std.heap.ArenaAllocator.init(std.heap.page_allocator),
        };
    }
    
    pub fn deinit(self: *ResponseArena) void {
        // Libera TUDO de uma vez — O(1)
        self.arena.deinit();
    }
};

3. SIMD e Vetorização

Zig facilita uso de instruções SIMD:

// Parsing de JSON com SIMD
const Vec16 = @Vector(16, u8);

fn findQuotes(data: []const u8) usize {
    var i: usize = 0;
    while (i + 16 <= data.len) : (i += 16) {
        const chunk: Vec16 = data[i..][0..16].*;
        const quotes = @intFromBool(chunk == @splat(@as(u8, '"')));
        // Processa 16 bytes de uma vez
    }
    // ...
}

4. Comptime para Otimização

Bun usa comptime para gerar código otimizado:

// Rotas parseadas em comptime
fn createRouter(comptime routes: []const Route) Router {
    comptime {
        // Parse todas as rotas em tempo de compilação
        // Gera tabela de hash perfeita
        // Zero overhead em runtime
    }
}

5. I/O Assíncrono Eficiente

Bun usa io_uring no Linux (via Zig) para I/O de alta performance:

// Simplificado — representação do approach
const IOUring = struct {
    ring: std.os.linux.IO_Uring,
    
    pub fn submitRead(self: *IOUring, fd: i32, buffer: []u8) !void {
        _ = try self.ring.read(0, fd, buffer, 0);
        _ = try self.ring.submit();
    }
};

Benchmarks Comparativos

OperaçãoNode.jsDenoBunGanho Bun
HTTP requests/sec60.00080.000195.0003.25x
Bundle React app1.2s0.8s0.05s24x
Start server120ms80ms35ms3.4x
Install deps45s30s8s5.6x
Run tests12s8s2s6x

Fonte: Benchmarks oficiais do Bun, fevereiro 2026


Desafios Técnicos e Soluções

Construir Bun não foi fácil. Veja os principais desafios e como foram resolvidos.

Desafio 1: Integração com JavaScriptCore

Problema: JSC é escrito em C++ com APIs C. Integrar com Zig requer bindings.

Solução:

// Exemplo simplificado de binding C
const JSC = @cImport({
    @cInclude("JavaScriptCore/JavaScript.h");
});

pub fn createString(ctx: JSC.JSContextRef, slice: []const u8) JSC.JSStringRef {
    return JSC.JSStringCreateWithUTF8CString(slice.ptr);
}

Zig permite importar headers C diretamente, tornando a integração trivial.

Desafio 2: Event Loop de Alta Performance

Problema: Event loop precisa lidar com milhares de conexões simultâneas.

Solução:

  • io_uring no Linux (I/O assíncrono do kernel)
  • kqueue no macOS
  • IOCP no Windows

Tudo escrito em Zig com controle total.

Desafio 3: Parsing TypeScript Rápido

Problema: TypeScript é complexo de parsear. tsc é lento.

Solução:

// Parser hand-written em Zig
// Otimizado para casos comuns
// Sem backtracking desnecessário
// SIMD para whitespace/identificadores

Desafio 4: Compatibilidade com Node.js

Problema: Milhares de pacotes npm dependem de APIs Node.js.

Solução:

  • Reimplementação das APIs core em Zig
  • Mock de APIs não-suportadas
  • Modo de compatibilidade progressivo

Desafio 5: Gerenciamento de Memória em Escala

Problema: Runtime JS aloca/desaloca constantemente.

Solução:

  • Arena allocators para requests
  • Object pools para objetos comuns
  • Integração com GC do JSC
  • Métricas de memória em tempo real

Comparativo: Bun vs Node.js vs Deno

AspectoNode.jsDenoBun
LinguagemC++RustZig
Lançamento200920202022
Engine JSV8V8JavaScriptCore
TypeScriptVia tscNativoNativo (mais rápido)
Bundlerwebpack/etcesbuildIntegrado
Package ManagernpmURL importsIntegrado (npm-compat)
Test Runnerjest/mochaBuilt-inBuilt-in (mais rápido)
HTTP PerformanceBaseline1.3x3x
Bundle Speed1x15x20x
Startup Time120ms80ms35ms
Tamanho~80MB~60MB~50MB

Quando Usar Cada Um?

Node.js:

  • ✅ Ecossistema maduro
  • ✅ Maior compatibilidade
  • ✅ Times grandes, projetos legados

Deno:

  • ✅ Segurança first-class
  • ✅ TypeScript nativo
  • ✅ Moderno, sem legacy

Bun:

  • Máxima performance
  • Tudo integrado
  • DX excelente
  • ⚠️ Ainda em desenvolvimento
  • ⚠️ Menor ecossistema

Projetos Similares em Zig

Bun não é o único projeto de destaque em Zig. A linguagem está sendo usada em:

TigerBeetle (Banco de dados financeiro)

  • O quê: Banco de dados ledger para finanças
  • Por quê Zig: Determinismo, zero GC, latência previsível
  • Performance: 1 milhão de transações/segundo
  • Links: tigerbeetle.com

Ghostty (Terminal emulator)

  • O quê: Terminal moderno escrito em Zig
  • Por quê Zig: Performance, cross-platform nativo
  • Features: GPU-accelerated, ligatures, split panes
  • Links: ghostty.org

Mach (Game engine)

  • O quê: Engine de jogos em Zig
  • Por quê Zig: Compilação rápida, hot-reload fácil
  • Status: Em desenvolvimento ativo

River (Window manager)

  • O quê: Tiling window manager para Wayland
  • Por quê Zig: Simplicidade, confiabilidade

Table Comparison

ProjetoDomínioStatusEstrelas
BunRuntime JSProdução70.000+
TigerBeetleDatabaseProdução10.000+
GhosttyTerminalBeta15.000+
MachGame EngineAlpha3.000+
RiverWindow ManagerProdução2.000+

Lições para Desenvolvedores Zig

O que podemos aprender com o sucesso do Bun?

1. Escolha Zig Quando Precisa de Controle

Se seu projeto precisa de:

  • ✅ Performance máxima
  • ✅ Controle de memória fino
  • ✅ Latência previsível (sem GC)
  • ✅ Interop com C

…Zig é provavelmente a melhor escolha.

2. Aproveite a Compilação Rápida

Jarred mencionou que a compilação rápida do Zig foi crucial para iteração:

“Com Zig, eu podia fazer uma mudança e ver o resultado em segundos. Isso muda como você programa.”

Prática: Use zig build run para desenvolvimento iterativo rápido.

3. Use Allocators Especializados

Bun não usa um allocator genérico. Cada componente tem sua estratégia:

// HTTP server: arena por request
// Parser: fixed buffer allocator
// Cache: pool allocator
// Geral: GPA em debug, Page em release

4. Interop com C é Trivial

Bun integra dezenas de bibliotecas C. Em Zig:

// Importar header C diretamente
const c = @cImport({
    @cInclude("libuv.h");
});

// Usar como se fosse código Zig
const loop = c.uv_default_loop();

Isso permite reaproveitar o ecossistema C existente.

5. Comptime para Otimização

Use comptime para mover trabalho para tempo de compilação:

// Parse config em comptime
// Gerar tabelas lookup
// Validar estados

6. Contribua para o Ecossistema

Bun tornou Zig mais visível. Mais projetos Zig = mais adoção = mais empregos.


Recursos e Referências

Sobre Bun

Artigos e Entrevistas

Benchmarks


Próximos Passos

Interessado em aprender mais sobre Zig através de projetos reais?

Conteúdo Relacionado

  1. TigerBeetle: Banco de Dados em Zig — Outro case study de produção
  2. Ghostty: Terminal Moderno em Zig — Aprenda com projetos desktop
  3. Zig vs Go: Qual Escolher? — Compare abordagens
  4. Gerenciamento de Memória em Zig — Domine allocators como o Bun
  5. Comptime em Zig — Otimizações em tempo de compilação

Projetos para Experimentar

  • Crie um servidor HTTP simples com Zig
  • Implemente um parser JSON básico
  • Construa uma CLI tool
  • Contribua para projetos open source em Zig

Recursos de Aprendizado


Conclusão

Bun prova que Zig é uma linguagem pronta para produção em projetos de alta escala. A combinação de:

  • Performance de C/C++
  • Simplicidade moderna
  • Controle explícito
  • Interop nativa

tornou possível criar um runtime JavaScript que compete com projetos de bilhões de dólares (Node.js, Deno).

Para desenvolvedores Zig, Bun é inspiração e validação: a linguagem funciona, escala, e está sendo usada para construir ferramentas que milhões de desenvolvedores usarão.

O futuro de Zig parece promissor — e projetos como Bun são apenas o começo.


Escrito por Camila para ZigLang Brasil. Última atualização: 10 de fevereiro de 2026.

Achou algum erro? Tem sugestões? Contribua no GitHub

Continue aprendendo Zig

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