TypeScript e Bun: o novo runtime

1. Introdução ao Bun como Runtime TypeScript

Bun é um runtime JavaScript moderno criado por Jarred Sumner, projetado desde sua concepção para ser rápido, completo e nativamente compatível com TypeScript. Diferente do Node.js (que exige transpilação via tsc ou ts-node) e do Deno (que oferece suporte nativo mas com peculiaridades de permissões), Bun executa arquivos .ts diretamente, sem qualquer etapa de compilação intermediária.

A relevância para o ecossistema TypeScript é imediata: desenvolvedores podem escrever código TypeScript e executá-lo como se fosse JavaScript, eliminando a fricção de configurar pipelines de build para scripts simples. A instalação é trivial:

# Linux/macOS
curl -fsSL https://bun.sh/install | bash

# Verificar instalação
bun --version

Para iniciar um projeto TypeScript com Bun:

mkdir meu-projeto && cd meu-projeto
bun init

O comando bun init gera automaticamente um tsconfig.json básico e um package.json, configurando o ambiente para execução imediata de arquivos .ts.

2. Execução Direta de TypeScript sem Compilação

Bun utiliza um transpilador interno escrito em Zig que processa TypeScript em tempo real, sem gerar arquivos .js intermediários (a menos que explicitamente solicitado). Isso significa que você pode executar:

// saudacao.ts
function saudacao(nome: string): string {
  return `Olá, ${nome}! Bem-vindo ao Bun.`;
}

console.log(saudacao("TypeScript"));

E rodar diretamente:

bun run saudacao.ts

O transpilador do Bun cobre a maior parte da sintaxe TypeScript, incluindo tipos genéricos, enums, namespaces e módulos. No entanto, existem limitações conhecidas: o Bun não realiza type-checking completo durante a execução — ele simplesmente remove as anotações de tipo e executa o JavaScript resultante. Para verificação de tipos, ainda é recomendado usar tsc --noEmit em paralelo.

3. Gerenciamento de Dependências e Tipos

Bun lê o tsconfig.json do projeto para entender configurações como target, module e strict. A resolução de módulos segue o algoritmo do Node.js, mas com otimizações significativas:

// Exemplo de tsconfig.json interpretado pelo Bun
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "strict": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

Para instalar tipos de bibliotecas, Bun usa o registro npm padrão:

bun add -d @types/node
bun add express @types/express

O cache de tipos do Bun é agressivo: após a primeira instalação, as resoluções de tipo são armazenadas localmente, reduzindo drasticamente o tempo de inicialização em execuções subsequentes.

4. Suporte a Recursos Avançados de TypeScript

Bun suporta decorators experimentais (no estilo TypeScript 5.x), const type parameters e outros recursos modernos:

// Decorator simples
function log(target: any, key: string) {
  console.log(`Chamando método: ${key}`);
}

class Exemplo {
  @log
  metodo() {
    return "executado";
  }
}

// const type parameters
function primeiroElemento<const T extends readonly any[]>(arr: T): T[0] {
  return arr[0];
}

const primeiro = primeiroElemento([1, "dois", true] as const);

Path aliases definidos no tsconfig.json são respeitados automaticamente:

// src/index.ts
import { helper } from "@/utils/helper";

Para projetos React com TypeScript, Bun oferece suporte nativo a JSX:

// componente.tsx
export function Botao({ texto }: { texto: string }) {
  return <button>{texto}</button>;
}

5. Ferramentas de Build e Scripts com Bun

Bun pode substituir completamente o tsc em pipelines de build para bundles de produção:

# Build de um arquivo TypeScript para bundle
bun build ./src/index.ts --outdir ./dist --target bun

# Com suporte a source maps
bun build ./src/index.ts --outdir ./dist --sourcemap=external

Para scripts de execução, bun run é significativamente mais rápido que alternativas:

# Comparação de inicialização
time bun run script.ts     # ~50ms
time ts-node script.ts     # ~800ms
time node --loader ts-node/esm script.ts  # ~1.2s

O bundler interno do Bun suporta code splitting, minificação e tree shaking, tudo com suporte nativo a TypeScript.

6. Debugging e Testes com TypeScript

Bun gera source maps automaticamente para arquivos TypeScript, permitindo debugging direto no código-fonte original:

// debug.ts
function calcular(a: number, b: number): number {
  debugger; // Ponto de interrupção
  return a + b;
}

console.log(calcular(5, 3));

Execute com bun --inspect debug.ts e conecte ao Chrome DevTools.

O test runner do Bun é nativamente compatível com TypeScript:

// soma.test.ts
import { describe, expect, test } from "bun:test";

function soma(a: number, b: number): number {
  return a + b;
}

describe("Função soma", () => {
  test("deve somar dois números positivos", () => {
    expect(soma(2, 3)).toBe(5);
  });

  test("deve somar números negativos", () => {
    expect(soma(-1, -2)).toBe(-3);
  });
});

Execute com bun test. Comparado ao Jest + ts-jest, os testes com Bun são tipicamente 3-5x mais rápidos na inicialização e execução.

7. Considerações de Performance e Compatibilidade

Benchmarks mostram que Bun supera Node.js e Deno em cenários típicos de TypeScript:

  • Inicialização: Bun ~50ms vs Node ~300ms vs Deno ~200ms
  • Execução de scripts: Bun 2-3x mais rápido em operações I/O intensivas
  • Testes: Bun test runner ~4x mais rápido que Jest com ts-jest

Em termos de compatibilidade, Bun implementa a maioria das APIs Node.js (fs, http, path, etc.), mas existem lacunas. Bibliotecas que dependem exclusivamente de tsc para compilação podem não funcionar corretamente. Para migração gradual:

// Use o arquivo .bunrc para configurações específicas
{
  "compilerOptions": {
    "strict": true
  },
  "modules": {
    "node": true  // Ativar compatibilidade com módulos Node.js
  }
}

8. Casos de Uso e Limitações

Casos ideais para Bun + TypeScript:
- APIs REST e GraphQL rápidas (Express, Hono, Elysia)
- Scripts CLI e ferramentas de automação
- Aplicações serverless e edge computing
- Prototipagem rápida com TypeScript

Limitações atuais:
- Sem type-checking em tempo real (delegado ao tsc)
- Ecossistema de plugins ainda imaturo
- Algumas bibliotecas Node.js não são totalmente compatíveis
- Debugging via IDEs ainda não é tão maduro quanto no Node.js

O futuro do Bun no ecossistema TypeScript é promissor. Com o suporte da comunidade e melhorias contínuas no transpilador, Bun está se consolidando como uma alternativa viável e, em muitos casos, superior ao Node.js para desenvolvimento TypeScript.


Referências