Bun es el runtime de JavaScript más rápido del mercado. En benchmarks de operaciones de E/S, servidor HTTP y arranque de procesos supera a Node.js y Deno por márgenes amplios. Detrás de esos números hay una decisión de diseño que muchos desarrolladores JavaScript desconocen: Bun está escrito en Zig, no en C ni en C++. Jarred Sumner, su creador, eligió Zig en 2021 cuando el lenguaje todavÃa estaba en versiones muy tempranas.
La arquitectura de Bun
Bun tiene tres capas principales. El motor JavaScript es JavaScriptCore (JSC), el motor de Apple usado en Safari, que en benchmarks de ejecución pura de JavaScript es competitivo o superior a V8 (el de Node.js y Deno). El runtime que rodea al motor, las APIs de Node.js, el sistema de ficheros, las conexiones de red y el servidor HTTP están escritos en Zig. Y el transpilador de TypeScript y JSX está también implementado en Zig, lo que explica en parte la velocidad de transpilación.
Por qué Zig para un runtime de JavaScript
Sumner eligió Zig por tres razones que él mismo ha explicado públicamente. La primera es el interop con C: JavaScriptCore es una biblioteca C/C++ y Zig puede incluir sus cabeceras directamente con @cImport sin ninguna capa de bindings. En Node.js, el puente entre V8 (C++) y el runtime está mediado por N-API, que añade overhead. En Bun, la integración con JSC es directa.
La segunda es el control de la memoria. En un runtime de JavaScript, el GC del motor ya gestiona los objetos JavaScript, pero todo lo demás (buffers de red, ficheros, strings internos, estructuras del runtime) puede gestionarse manualmente. Con Zig, Sumner puede decidir exactamente cómo se organiza la memoria para cada tipo de dato, lo que reduce la presión sobre el GC de JSC y mejora la localidad de caché.
La tercera es la velocidad de compilación y la facilidad de cross-compilation. Bun distribuye binarios para Linux x86_64, Linux ARM64, macOS x86_64 y macOS ARM64. Con Zig, la pipeline de cross-compilation es sencilla.
Comparación de rendimiento
Benchmark | Node.js 22 | Deno 2 | Bun 1.x |
Arranque (ms) | ~80ms | ~30ms | ~5ms |
Servidor HTTP (req/s) | ~70k | ~80k | ~120k |
Lectura de ficheros | base | similar | 2-3x más rápido |
SQLite (ops/s) | via better-sqlite3 | via FFI | nativo, más rápido |
Los números exactos dependen del benchmark especÃfico y de la versión, pero el patrón general es consistente: Bun es significativamente más rápido en operaciones de E/S y en arranque, y competitivo en ejecución pura de JavaScript.
Lo que Bun ofrece además del runtime
Bun no solo reemplaza Node.js como runtime. También incluye:
- Gestor de paquetes:
bun installes 10-25x más rápido quenpm install. Usa un formato de lockfile binario propio y caché agresiva. - Transpilador nativo: TypeScript y JSX se transpilan sin
tscni Babel. Escrito en Zig, es mucho más rápido que las alternativas JS. - Bundler:
bun buildproduce bundles de producción sin Webpack ni esbuild. - Test runner:
bun testes compatible con la API de Jest pero más rápido. - SQLite nativo:
bun:sqlitees una API nativa para SQLite sin dependencias externas.
Compatibilidad con Node.js
Bun implementa la mayorÃa de las APIs de Node.js y es compatible con npm. La mayorÃa de proyectos Node.js funcionan en Bun sin cambios. Las diferencias están en APIs muy especÃficas o en comportamientos edge case del event loop. Para proyectos nuevos, Bun es una opción directa. Para proyectos existentes, la migración suele ser sencilla.
# Instalar Bun
curl -fsSL https://bun.sh/install | bash
# Instalar dependencias de un proyecto Node.js existente
bun install
# Ejecutar un script
bun run index.ts # TypeScript directamente, sin transpilación previa
# Servidor HTTP mÃnimo en Bun
bun --eval "Bun.serve({ fetch(req) { return new Response('hola'); }, port: 3000 })"
Zig en producción: la lección de Bun y TigerBeetle
Bun y TigerBeetle son los dos proyectos más importantes escritos en Zig que están en producción real. Los dos eligieron Zig por razones similares: interop directo con C sin overhead, control total de la memoria y ausencia de runtime oculto. Los dos son proyectos donde el rendimiento no es un nice-to-have sino una caracterÃstica central del producto.
Esto dice algo sobre dónde encaja Zig mejor: no es para cualquier proyecto, pero para los proyectos donde el rendimiento de bajo nivel importa, tiene ventajas reales sobre las alternativas. Si quieres ver cómo Bun gestiona la interop con JavaScriptCore (que es una biblioteca C), el artÃculo sobre interop Zig-C explica el mecanismo que hace posible esa integración. Y para entender el contexto completo del lenguaje, el artÃculo de introducción a Zig con el que empieza esta serie es el punto de partida. También puedes leer más sobre Bun en el artÃculo especÃfico sobre Bun 1.3.
Imagen: Pexels / Robin Schreiner
