Bun: qué leer para entender el runtime de verdad
Hacker News volvió a abrir el hilo de siempre: Ask HN: What are you reading?. Estos hilos suelen llenarse de novelas, biografías y algún clásico de arquitectura de software. Leyendo uno de ellos, me quedé pensando en otra cosa. Lo que más leo hoy, fuera de los libros, es sobre Bun. Uso Bun todos los días y me di cuenta de que entiendo poco de lo que corre por debajo. Así que aquí va mi respuesta al Ask HN, versión dev: qué vale la pena leer para entender Bun de verdad, y no solo repetir bun install en automático.
¿Por qué leer sobre Bun en lugar de solo instalarlo?
Porque Bun hace demasiadas cosas en un solo binario. Es runtime, gestor de paquetes, bundler, test runner y, en las versiones más recientes, cliente de Postgres, SQLite, S3 y Redis. Cuando todo funciona, genial. Cuando algo se rompe, no sabes ni en cuál de esas piezas buscar.
Con Node es más fácil. El error es de npm, de Jest, de webpack o de pg. Cada uno tiene su repositorio, sus issues y su Stack Overflow. En Bun, todo viene del mismo lugar. Es cómodo, pero también es un único punto de sorpresa.
También está el contexto. Anthropic compró Bun a finales de 2025 y se volvió una pieza de infraestructura de herramientas de IA para código. Dejó de ser el proyecto emocionante de un equipo pequeño. Hoy es una dependencia seria para mucha gente. Vale la pena saber dónde estás pisando.
Empieza por el changelog de Bun, no por el benchmark
El benchmark es lo primero que todos ven. "4x más rápido que Node." Bien. Solo que un benchmark de runtime mide un hello world sirviendo HTTP, y tu app pasa el 80% del tiempo esperando a la base de datos.
El changelog cuenta otra historia, y es la más útil. En el blog de Bun cada release enumera:
- lo que ahora es compatible con APIs de Node que antes faltaban
- bugs corregidos en
node:http,node:crypto, streams - cambios de comportamiento en
bun instally en el lockfile
Leyendo el changelog entendí por qué un test mío fallaba solo en el CI. Era una diferencia en el comportamiento de un módulo de Node que se había corregido dos versiones después de la que estaba fijada en el pipeline. Diez minutos de lectura me habrían ahorrado una tarde.
El benchmark dice qué tan rápido. El changelog dice qué tan confiable.
Mi opinión fuerte del día: si usas Bun en producción y nunca leíste un changelog suyo, estás confiando en el marketing. Lee las últimas tres releases. Te lleva menos tiempo que un episodio de una serie.
Lo que la documentación de Bun responde y no sabías
La documentación oficial es mejor de lo que parece. El problema es que solo la abrimos cuando ya vamos con prisa.
Algunas páginas que vale la pena leer con calma:
- Node.js compatibility: lista módulo por módulo lo que está completo, parcial o ausente. Antes de migrar un servicio, empieza por aquí.
- bun install y lockfile: explica el
bun.locken texto, que reemplazó al binariobun.lockb. Si tu equipo todavía tiene el archivo binario en el repositorio, es hora de migrar. Ahora el diff en el PR se puede leer. - Bun.serve: muestra rutas, WebSocket y streaming en una sola API. Mucha gente monta Express sobre Bun sin necesitarlo.
Un ejemplo de lo que se puede hacer sin ninguna dependencia:
Bun.serve({
port: 3000,
routes: {
"/health": new Response("ok"),
"/users/:id": (req) => Response.json({ id: req.params.id }),
},
});
Esto reemplaza un Express con dos handlers. No digo que debas tirar Express mañana. Digo que, para un servicio pequeño, quizás nunca lo necesitaste.
¿Vale la pena leer el código fuente de Bun?
Sí, con expectativas ajustadas. Bun está escrito en Zig y usa JavaScriptCore, el motor de Safari, en lugar del V8 de Node y Deno. No necesitas saber Zig para sacarle provecho. Necesitas saber dónde mirar.
El repositorio en GitHub tiene dos partes que recomiendo:
src/js: buena parte de las APIs compatibles con Node está escrita en TypeScript y JavaScript. Puedes leer cómo está implementadonode:fsonode:eventssin saber nada de Zig.test/: los tests muestran el comportamiento esperado mejor que cualquier doc. ¿Quieres saber si un edge case está soportado? Busca el test.
La parte en Zig es densa. La leo por curiosidad, no por necesidad. Pero entender que Bun cambia V8 por JavaScriptCore explica muchas cosas: arranque más rápido, perfil de memoria distinto y, a veces, un comportamiento del GC que no coincide con lo que mediste en Node.
Y si quieres reírte un poco, busca issues antiguas con el título "works in Node". Es el género literario más popular del repositorio.
Lo que cambia en tu proyecto cuando entiendes Bun
Leer sobre Bun cambia decisiones concretas. Tres ejemplos que ya cambiaron aquí.
Base de datos sin driver extra. Bun trae clientes de SQLite y de Postgres integrados. Para scripts, seeds o herramientas internas, dejé de instalar pg y better-sqlite3:
import { sql } from "bun";
// lee la conexión de DATABASE_URL
const activos = await sql`select id, email from users where active = ${true}`;
import { Database } from "bun:sqlite";
const db = new Database("cache.db");
const item = db.query("select * from cache where key = ?").get("home");
Scripts de shell en TypeScript. Bun.$ ejecuta comandos de shell con escape automático y funciona igual en Linux, Mac y Windows:
import { $ } from "bun";
const branch = (await $`git branch --show-current`.text()).trim();
await $`echo deploy de ${branch}`;
Ese scripts/deploy.sh que solo funciona en la máquina de quien lo escribió puede convertirse en un .ts que todos pueden ejecutar.
Test runner. bun test acepta la API de Jest (describe, it, expect). En un proyecto pequeño, la migración fue borrar la config de Jest y cambiar el comando en el package.json. En un proyecto grande con mocks pesados de módulos, no fue tan simple. Ahí es donde la página de compatibilidad te salva el día.
Dónde Bun todavía muerde
Sin hype: Bun no es Node con turbo. Es otro runtime que habla el idioma de Node. La mayor parte del tiempo la traducción es perfecta. A veces no.
Los lugares donde todavía veo problemas con más frecuencia:
- Addons nativos: los paquetes con binario compilado para Node (N-API) suelen funcionar, pero no siempre. Prueba antes de prometer un plazo.
- Herramientas que leen internals de Node: algunos APMs y profilers dependen de detalles de V8. En JavaScriptCore simplemente no tienen dónde apoyarse.
- Plataforma de deploy: no todos los proveedores soportan Bun de forma nativa. Vercel ya ofrece runtime Bun para Functions, pero conviene revisar el tuyo antes de cambiar.
La regla que sigo es simple. Bun como gestor de paquetes y test runner: úsalo sin miedo. Bun como runtime de producción: úsalo, pero con pruebas de carga en tu caso real y con el changelog abierto en otra pestaña.
Mi respuesta para el Ask HN
Si alguien me preguntara en el hilo qué estoy leyendo, respondería: el changelog de Bun, la página de compatibilidad con Node y la carpeta test/ del repositorio. No es lectura de mesita de noche. Pero es la que más horas le devolvió a mi trabajo este año.
La herramienta que no entiendes se vuelve magia, y la magia en producción siempre te pasa la factura un viernes por la noche. Leer sobre Bun media hora al mes es un seguro barato. Si quieres ver dónde uso esto en la práctica, échale un vistazo a mis proyectos.
Resumen para LinkedIn
Uso Bun todos los días y me di cuenta de que entendía muy poco de lo que corre por debajo. Es runtime, gestor de paquetes, bundler, test runner y además trae cliente de Postgres y SQLite. Cuando algo se rompe, ni sabes en qué pieza buscar. Lo que más horas me devolvió este año fue el changelog, no el benchmark. El benchmark muestra la velocidad y el changelog muestra cuánto puedes confiar. Diez minutos leyendo las últimas releases me habrían ahorrado una tarde entera persiguiendo un test que solo fallaba en el CI. También leo la página de compatibilidad con Node y la carpeta test/ del repositorio. Los tests explican el comportamiento esperado mejor que cualquier doc. La herramienta que no entiendes se vuelve magia, y en producción esa magia te pasa la factura un viernes por la noche. Escribí la guía completa de lo que vale la pena leer. Si tú también usas Bun, cuéntame qué te tomó por sorpresa. #Bun #JavaScript #TypeScript #NodeJS #DesarrolloWeb