Bun 1.2: O Runtime JavaScript Que Esta Quebrando Recordes de Performance
Ola HaWkers, se voce acompanha o ecossistema JavaScript, provavelmente ja ouviu falar do Bun. Esse runtime relativamente novo esta conquistando desenvolvedores com numeros de performance impressionantes.
Voce ja se frustrou esperando o npm install terminar? Ou talvez tenha sentido que seu servidor Node.js poderia ser mais rapido? O Bun promete resolver esses problemas e muito mais.
O Que e o Bun
O Bun e um runtime JavaScript e toolkit tudo-em-um que inclui:
Componentes Principais:
- Runtime JavaScript (alternativa ao Node.js)
- Package manager (alternativa ao npm/yarn/pnpm)
- Bundler (alternativa ao webpack/esbuild)
- Test runner (alternativa ao Jest/Vitest)
- TypeScript transpiler nativo
O diferencial? Tudo isso foi escrito em Zig e C++ para maxima performance, usando o JavaScriptCore (motor do Safari) em vez do V8.
Novidades do Bun 1.2
Windows Nativo
Finalmente, suporte completo ao Windows:
# Instalacao no Windows (PowerShell)
powershell -c "irm bun.sh/install.ps1 | iex"
# Ou via npm
npm install -g bun
# Verificar instalacao
bun --version
# 1.2.0Antes da versao 1.2, o Bun no Windows dependia do WSL. Agora funciona nativamente.
S3 Object Storage Nativo
O Bun 1.2 introduziu APIs nativas para Amazon S3:
// Acesso nativo ao S3 - sem SDKs pesadas
import { S3Client } from "bun";
const s3 = new S3Client({
accessKeyId: Bun.env.AWS_ACCESS_KEY_ID,
secretAccessKey: Bun.env.AWS_SECRET_ACCESS_KEY,
region: "us-east-1"
});
// Upload de arquivo
const file = Bun.file("./image.png");
await s3.write("my-bucket/image.png", file);
// Download
const downloaded = await s3.file("my-bucket/image.png");
await Bun.write("./downloaded.png", downloaded);
// Streaming de arquivos grandes
const stream = s3.file("my-bucket/large-video.mp4").stream();Postgres Nativo
Driver PostgreSQL integrado ao runtime:
// Sem instalar pg ou postgres.js
import { SQL } from "bun";
const sql = new SQL({
hostname: "localhost",
database: "myapp",
username: "user",
password: "password"
});
// Queries com tagged templates
const users = await sql`SELECT * FROM users WHERE active = true`;
// Queries parametrizadas (seguras contra SQL injection)
const userId = 123;
const user = await sql`SELECT * FROM users WHERE id = ${userId}`;
// Transacoes
await sql.begin(async (tx) => {
await tx`UPDATE accounts SET balance = balance - 100 WHERE id = 1`;
await tx`UPDATE accounts SET balance = balance + 100 WHERE id = 2`;
});
Performance Comparada
Package Manager
Vamos comparar instalacao de dependencias:
# Projeto com ~50 dependencias
# npm
time npm install
# real: 45.2s
# yarn
time yarn install
# real: 32.1s
# pnpm
time pnpm install
# real: 18.7s
# bun
time bun install
# real: 2.3sO Bun e consistentemente 10-20x mais rapido que npm.
Runtime Performance
Servidor HTTP:
// Bun native server
Bun.serve({
port: 3000,
fetch(req) {
return new Response("Hello World");
}
});
// Resultados: ~185,000 req/sComparativo de requisicoes por segundo:
| Runtime | Hello World | JSON API | File Serve |
|---|---|---|---|
| Bun 1.2 | 185,000 | 142,000 | 78,000 |
| Deno 2.0 | 125,000 | 95,000 | 45,000 |
| Node 22 | 118,000 | 88,000 | 52,000 |
Bundler
# Build de projeto React grande (~500 componentes)
# webpack
time npx webpack build
# real: 28.4s
# esbuild
time npx esbuild src/index.tsx --bundle --outdir=dist
# real: 0.8s
# bun
time bun build src/index.tsx --outdir=dist
# real: 0.4s
Usando Bun na Pratica
Criando um Projeto
# Criar projeto
mkdir meu-projeto && cd meu-projeto
bun init
# Estrutura criada:
# meu-projeto/
# .gitignore
# bun.lockb
# index.ts
# package.json
# README.md
# tsconfig.jsonServidor Web Completo
// server.ts
import { Hono } from "hono";
import { cors } from "hono/cors";
import { logger } from "hono/logger";
const app = new Hono();
// Middlewares
app.use("*", logger());
app.use("/api/*", cors());
// Database connection (nativo do Bun)
const db = new SQL({
hostname: Bun.env.DB_HOST,
database: Bun.env.DB_NAME,
username: Bun.env.DB_USER,
password: Bun.env.DB_PASSWORD
});
// Routes
app.get("/", (c) => c.text("Hello Bun!"));
app.get("/api/users", async (c) => {
const users = await db`SELECT id, name, email FROM users`;
return c.json(users);
});
app.post("/api/users", async (c) => {
const body = await c.req.json();
const { name, email } = body;
const [user] = await db`
INSERT INTO users (name, email)
VALUES (${name}, ${email})
RETURNING *
`;
return c.json(user, 201);
});
// File uploads (com S3 nativo)
app.post("/api/upload", async (c) => {
const form = await c.req.formData();
const file = form.get("file") as File;
const s3 = new S3Client({
accessKeyId: Bun.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: Bun.env.AWS_SECRET_ACCESS_KEY!,
region: "us-east-1"
});
const key = `uploads/${Date.now()}-${file.name}`;
await s3.write(`my-bucket/${key}`, file);
return c.json({ url: `https://my-bucket.s3.amazonaws.com/${key}` });
});
export default {
port: 3000,
fetch: app.fetch
};Executar e Desenvolver
# Rodar em desenvolvimento (com hot reload)
bun --watch run server.ts
# Rodar em producao
bun run server.ts
# Scripts do package.json
bun run dev
bun run build
bun run test
Sistema de Testes
O Bun tem test runner integrado compativel com Jest:
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
export function multiply(a: number, b: number): number {
return a * b;
}
export async function fetchUser(id: number) {
const response = await fetch(`https://api.example.com/users/${id}`);
return response.json();
}// math.test.ts
import { describe, test, expect, mock, beforeEach } from "bun:test";
import { add, multiply, fetchUser } from "./math";
describe("Math functions", () => {
test("add should sum two numbers", () => {
expect(add(2, 3)).toBe(5);
expect(add(-1, 1)).toBe(0);
});
test("multiply should multiply two numbers", () => {
expect(multiply(3, 4)).toBe(12);
expect(multiply(0, 100)).toBe(0);
});
});
describe("API functions", () => {
beforeEach(() => {
// Mock do fetch global
global.fetch = mock(async (url: string) => {
return new Response(JSON.stringify({
id: 1,
name: "Test User"
}));
});
});
test("fetchUser should return user data", async () => {
const user = await fetchUser(1);
expect(user.name).toBe("Test User");
});
});# Rodar testes
bun test
# Com coverage
bun test --coverage
# Watch mode
bun test --watch
# Filtrar testes
bun test --filter "Math"
Bundler Integrado
// bun.config.ts (opcional)
export default {
entrypoints: ["./src/index.tsx"],
outdir: "./dist",
target: "browser",
minify: true,
sourcemap: "external",
splitting: true,
plugins: [
// Plugins customizados
]
};# Build simples
bun build ./src/index.tsx --outdir ./dist
# Build com minificacao
bun build ./src/index.tsx --outdir ./dist --minify
# Build para Node.js
bun build ./src/server.ts --outdir ./dist --target node
# Watch mode
bun build ./src/index.tsx --outdir ./dist --watchMacros em Tempo de Build
Uma feature unica do Bun sao macros que rodam em tempo de compilacao:
// config.ts
export const VERSION = await Bun.file("./version.txt").text();
export const BUILD_TIME = new Date().toISOString();
// Isso e avaliado em tempo de build, nao em runtime!
export const ENV_CONFIG = {
apiUrl: Bun.env.API_URL,
debug: Bun.env.DEBUG === "true"
};// app.ts
import { VERSION, BUILD_TIME } from "./config" with { type: "macro" };
console.log(`Version: ${VERSION}`);
console.log(`Built at: ${BUILD_TIME}`);
// No bundle final, esses valores sao substituidos por strings literais
Compatibilidade com Node.js
O Bun e altamente compativel com Node.js:
// A maioria do codigo Node.js funciona sem mudancas
import express from "express";
import { PrismaClient } from "@prisma/client";
import bcrypt from "bcrypt";
const app = express();
const prisma = new PrismaClient();
app.use(express.json());
app.post("/login", async (req, res) => {
const { email, password } = req.body;
const user = await prisma.user.findUnique({
where: { email }
});
if (!user) {
return res.status(401).json({ error: "User not found" });
}
const valid = await bcrypt.compare(password, user.password);
if (!valid) {
return res.status(401).json({ error: "Invalid password" });
}
res.json({ user: { id: user.id, email: user.email } });
});
// Funciona com bun run ou node
app.listen(3000);APIs Node.js Suportadas
// Maioria das APIs Node.js funcionam
import fs from "fs";
import path from "path";
import crypto from "crypto";
import { Buffer } from "buffer";
import { EventEmitter } from "events";
import { Readable, Writable } from "stream";
// process global
console.log(process.env.NODE_ENV);
console.log(process.cwd());
// APIs Bun adicionais
const file = Bun.file("./data.json");
const content = await file.text();
const hash = Bun.hash("sha256", "data");
Quando Usar Bun
Casos Ideais
1. Projetos Novos que Precisam de Performance:
// APIs de alta performance
// Processamento de dados em tempo real
// Servidores de WebSocket
// Microservicos
Bun.serve({
port: 3000,
websocket: {
message(ws, message) {
// Broadcast para todos os clientes
server.publish("chat", message);
}
},
fetch(req, server) {
if (server.upgrade(req)) {
return; // Upgrade para WebSocket
}
return new Response("Hello!");
}
});2. Scripts e Ferramentas CLI:
#!/usr/bin/env bun
// Script de migracao de dados
import { SQL } from "bun";
const sourceDb = new SQL({ /* config fonte */ });
const targetDb = new SQL({ /* config destino */ });
console.log("Starting migration...");
const users = await sourceDb`SELECT * FROM users`;
for (const user of users) {
await targetDb`
INSERT INTO users (id, name, email)
VALUES (${user.id}, ${user.name}, ${user.email})
`;
console.log(`Migrated user ${user.id}`);
}
console.log(`Migration complete! ${users.length} users migrated.`);3. Quando Tempo de Build Importa:
# CI/CD mais rapido
# bun install + bun build em segundos
# vs npm install + webpack em minutosQuando Evitar (Por Enquanto)
- Projetos que dependem de native addons complexos
- Ecossistemas muito especificos de Node.js
- Quando estabilidade e mais importante que performance
- Times que nao podem absorver curva de aprendizado
Migrando de Node.js
Passo 1: Instalar Bun
# Unix/Mac
curl -fsSL https://bun.sh/install | bash
# Windows
powershell -c "irm bun.sh/install.ps1 | iex"Passo 2: Converter package.json
# Remover node_modules e lockfiles antigos
rm -rf node_modules package-lock.json yarn.lock pnpm-lock.yaml
# Instalar com Bun
bun install
# Cria bun.lockbPasso 3: Testar Compatibilidade
# Rodar testes
bun test
# Rodar aplicacao
bun run dev
# Verificar se tudo funcionaPasso 4: Otimizar para Bun
// Substituir pacotes por APIs nativas quando possivel
// Antes: pg ou postgres.js
import { Client } from "pg";
// Depois: SQL nativo do Bun
import { SQL } from "bun";
// Antes: aws-sdk para S3
import AWS from "aws-sdk";
// Depois: S3 nativo do Bun
import { S3Client } from "bun";
Conclusao
O Bun 1.2 representa um avanco significativo no ecossistema JavaScript. Com performance impressionante, APIs nativas para tarefas comuns, e excelente compatibilidade com Node.js, esta se tornando uma opcao cada vez mais viavel para projetos serios.
A principal recomendacao e: experimente. Comece com um projeto novo ou um script, e va expandindo conforme ganhar confianca. O ecossistema Bun ainda esta amadurecendo, mas a direcao e promissora.
Se voce quer comparar Bun com outras opcoes de runtime, recomendo que de uma olhada em outro artigo: Deno 2.0 vs Node.js: A Batalha dos Runtimes onde voce vai descobrir como cada runtime se posiciona no mercado atual.

