Ir al contenido
Web

Bun vs Node en 2026: cuándo gana cada runtime en producción

Bun 1.3 trae un runtime full-stack; Node 24, TypeScript nativo y test runner. Usamos Bun para instalar y testear, Node para el código que aguanta tráfico.

4 de septiembre de 2026 · 7 min de lectura · Actualizado el 12 de octubre de 2026

Left, eight short white bars racing to a finish line with fading trails; right, one lit tile with steady streams of dots flowing through it

Bun es un runtime de JavaScript construido sobre JavaScriptCore que mete en el mismo binario el gestor de paquetes, el test runner y el bundler, y aspira a ejecutar sin tocar nada el código escrito para Node. Node es el runtime contra el que se escribió todo el registro npm, y el que viene por defecto en casi cualquier plataforma gestionada que ejecute el código por ti.

La decisión aparece en dos momentos: cuando levantas un servicio nuevo y cuando los tiempos de instalación o la factura de CI empiezan a doler. En la encuesta State of JavaScript 2025, el 90% de quienes respondieron dice usar Node y el 21% dice usar Bun, cuatro puntos más que el año anterior, con Deno en el 11% (State of JS 2025). No es una clasificación. Casi todos los equipos que usan Bun usan también Node, en sitios distintos del mismo repositorio.

La respuesta en treinta segundos

Bun encaja donde el trabajo dura poco y la máquina es tuya: instalaciones, tests, scripts, servidores de desarrollo local, utilidades de un solo uso. Node encaja donde el proceso queda encendido, da la cara al público y arrastra paquetes que no has escrito tú. Si tienes que elegir un único runtime para un backend SaaS que dentro de dieciocho meses siga en pie, elige Node y deja que Bun se gane el sitio empezando por la CI.

Qué cambia de verdad entre Bun y Node

  • Motor. Bun corre sobre JavaScriptCore, el motor de Safari. Node corre sobre V8. Cambia el comportamiento del recolector de basura, cambia el calentamiento del JIT y cambia el perfil de memoria bajo carga sostenida.
  • Alcance. Bun es runtime más gestor de paquetes más test runner más bundler. Node es un runtime que por el camino ha incorporado un test runner y, desde la 24, el borrado de tipos de TypeScript.
  • Dirección de la compatibilidad. Bun implementa las API de Node. Node no implementa las de Bun. Desde que escribes Bun.serve o bun:sqlite, ese código solo corre en Bun.
  • Ritmo de publicación. Bun saca una versión menor casi cada semana. Node saca una major en abril y otra en octubre, y mantiene cada línea LTS treinta meses.
  • Dónde existe como runtime gestionado. Node lo tiene en todas las plataformas serverless que cuentan. Bun lo tiene en Vercel Functions, en beta pública, y en AWS Lambda no.

Dónde gana Bun

Instalaciones y tiempo de CI

Es la ventaja menos discutible. Los benchmarks independientes de 2026 miden una instalación en frío de un proyecto con cincuenta dependencias por debajo del segundo con bun install, frente a unos catorce segundos de npm; pnpm queda en medio y recupera casi toda la distancia cuando la caché de CI está caliente (benchmark de PkgPulse). En un monorepo eso son minutos por ejecución, en cada ejecución y para cada persona del equipo.

Esta ventaja la puedes coger sin adoptar Bun como runtime. bun install escribe un lockfile y un node_modules normal, y luego Node ejecuta el resultado. Ahora bien, si la instalación va lenta porque el árbol es enorme y no porque npm sea lento, el problema está más arriba, en la proliferación de dependencias, y un instalador más rápido solo lo tapa.

Un binario en lugar de cuatro herramientas

Un servicio nuevo escrito para Bun no necesita Jest, ni Vitest, ni tsx, ni configuración de esbuild. bun test ejecuta TypeScript directamente, bun build empaqueta y bun --hot recarga. La 1.3, publicada en octubre de 2025, añadió clientes integrados de Postgres, MySQL y Redis, más un servidor de desarrollo que sirve un index.html, resuelve módulos ES y recarga en caliente sin ninguna configuración (notas de la versión Bun 1.3).

El ahorro se ve en los ficheros de configuración que no escribes y que no tendrás que actualizar. En un servicio interno pequeño eso vale más que cualquier cifra de throughput.

Scripts y utilidades locales

Todo lo que habrías escrito como script de shell con el shebang de Node está mejor en Bun. Arranca antes, lee TypeScript sin paso de build y trae en la librería estándar las ayudas para ficheros y comandos del sistema. El arranque en frío es donde la ventaja de JavaScriptCore se nota más, y un script es todo arranque en frío.

Throughput bruto, con un asterisco

En los benchmarks HTTP sintéticos Bun le saca mucho a Node. La 1.3 informa de Express un 9% más rápido y Fastify un 5,4% más rápido que la versión anterior, con el consumo de memoria de JavaScript entre un 10% y un 30% más bajo (notas de la versión Bun 1.3). En un servicio que consulta Postgres en cada petición, el runtime casi nunca es el cuello de botella y la diferencia de punta a punta se queda en unos pocos puntos. El throughput sirve para desempatar, no para justificar la decisión.

Dónde gana Node

Los módulos nativos

El obstáculo habitual es el código nativo: paquetes compilados contra la N-API de Node. sharp, bcrypt, better-sqlite3, casi todo lo que todavía pasa por node-gyp, cualquier cosa que distribuya un binario precompilado por plataforma. Bun publica su cobertura de las API de Node módulo a módulo y marca las implementaciones parciales, incluidas las reservas sobre N-API (compatibilidad de Bun con las API de Node.js). Esa página se lee contra tu propio árbol de dependencias antes de decidir, no después del primer despliegue fallido.

Serverless gestionado

Los runtimes Node gestionados de AWS Lambda cubren la 22, la 24 y la 26, con la 26 en vista previa pública desde agosto de 2026 (AWS Compute Blog). Un runtime Bun gestionado en Lambda no existe. Vercel sí ejecuta Bun en Functions en beta pública, de momento con Next.js, Express, Hono y Nitro (documentación de Vercel): es un avance real, y sigue siendo una beta pública para el proceso que atiende a tus clientes. El mismo razonamiento vale un nivel más abajo cuando eliges entre edge runtime y Node runtime: el límite es qué te opera la plataforma, no qué rinde bien en un portátil.

La distancia que Node ha cerrado

En 2023 buena parte de los argumentos a favor de Bun eran de ergonomía, y Node ha pasado dos años desmontándolos. La 24 ejecuta node app.ts con borrado de tipos estable: sin paso por tsc, sin carpeta de build, sin source maps que arrastrar (documentación de TypeScript en Node.js). El require() de un módulo ES funciona por defecto desde la 23 (notas de la versión Node 23). node --test trae aserciones, mocks, cobertura, modo watch y ejecución en paralelo sin instalar nada (documentación de node:test). La 24 es Active LTS con soporte hasta abril de 2028, y la 26 entra en LTS en octubre de 2026 (versiones de Node.js).

El borrado de tipos no comprueba tipos: borra las anotaciones y ejecuta lo que queda. Así que tsc --noEmit en CI sigue haciendo falta, y ahí es donde el compilador de TypeScript escrito en Go cambia las cuentas.

Cómo decidirlo en diez minutos

  1. Busca en el árbol de dependencias los paquetes que traen un fichero .node o una build de node-gyp. Si encuentras alguno, en producción va Node.
  2. Mira dónde acaba el código. Lambda, una imagen base que no controlas o el clúster de un cliente significan Node en los tres casos.
  3. Cronometra el paso de instalación en CI. Por encima de sesenta segundos, muévelo a Bun esta semana y deja el runtime en paz.
  4. Cronometra la suite de tests. Una ejecución de Jest o Vitest por encima de noventa segundos justifica una prueba con bun test en una rama.
  5. Pregunta quién lleva la guardia. Dos años de rodaje en producción dentro del equipo ganan a dos semanas, diga lo que diga el benchmark.

Qué usamos nosotros y por qué

Usamos Node para todo lo que sirve tráfico y Bun para todo lo que hay alrededor. En Node corren nuestras builds de Next.js y las rutas de API apoyadas en Supabase, porque es lo que ofrecen los runtimes de las plataformas y nuestras imágenes de contenedor, y porque en esos árboles de dependencias hay módulos nativos. Bun ejecuta instalaciones y tests unitarios en CI, y mueve los scripts de mantenimiento y de contenido de nuestros repositorios, donde un arranque de 40ms le gana a uno de 300ms varios cientos de veces al día.

Lo que sostiene el montaje es una sola regla: ninguna API exclusiva de Bun dentro del código de aplicación. Nada de Bun.serve, nada de bun:sqlite, nada de Bun.file en algo que pueda acabar en un servidor. Escrito así, el runtime que hay debajo de un servicio sigue siendo una decisión de despliegue reversible en una tarde en vez de una reescritura que hay que planificar. Hoy esa restricción no nos cuesta casi nada, y es la razón por la que dentro de un año nuestra respuesta a esta pregunta puede cambiar sin hacer daño a nadie.

Preguntas frecuentes

Servicios relacionados

Studio

Empieza un proyecto.

Escribimos sobre lo que construimos. Cuéntanos qué quieres construir tú.