Daniel Murillo
Índice

Arquitectura · 28 de octubre de 2026 · Daniel Murillo

Node.js vs Bun vs Deno: cómo elegir un runtime para backend en 2026

No elijas solo por requests/s. Ecosistema, compatibilidad, operación y el rendimiento de tu aplicación real.

No elijas un runtime solo por una tabla de requests por segundo. Evalúa el ecosistema que necesitas, la compatibilidad de tus dependencias, la operación en producción y el rendimiento de tu aplicación real.

1. La pregunta correcta no es «¿cuál es el más rápido?»

Node.js, Bun y Deno ejecutan JavaScript y TypeScript, pero nacieron con prioridades diferentes:

  • Node.js: compatibilidad, madurez, ecosistema y operación probada a escala. En octubre de 2026, Node.js 26 entra en Active LTS; 24 pasa a mantenimiento.
  • Bun: velocidad de arranque, herramientas integradas y rendimiento; busca ser un runtime y también una caja de herramientas. Bun 1.4 apunta a compatibilidad con Node 26 y documenta una reescritura mayor del runtime.
  • Deno: seguridad por permisos, estándares web, TypeScript directo y tooling integrado. Deno 2.9 mejora arranque/memoria HTTP y añade deno desktop además de mejor lectura de lockfiles npm/pnpm/Yarn/Bun.

Hoy la elección ya no se reduce a «Node es el único listo para producción». Bun y Deno han avanzado bastante en compatibilidad y capacidades. Pero tampoco es correcto concluir que ya son sustitutos idénticos: las diferencias aparecen en dependencias nativas, APIs de Node, herramientas de observabilidad, despliegues y comportamientos específicos.

La decisión debería responder estas preguntas:

  1. ¿Qué librerías necesita el proyecto y qué APIs usan?
  2. ¿Qué frameworks, drivers y herramientas de observabilidad se van a ejecutar?
  3. ¿Cuánto importa el tiempo de arranque, la memoria o el throughput?
  4. ¿En qué plataforma se desplegará?
  5. ¿Qué tan costoso sería investigar y resolver una incompatibilidad?
  6. ¿El equipo necesita estabilidad conservadora o quiere aprovechar herramientas nuevas?

2. Comparativa rápida

DimensiónNode.jsBunDeno
Motor JavaScriptV8JavaScriptCoreV8
Prioridad históricaEcosistema y compatibilidadRendimiento y herramientas integradasSeguridad, estándares web y DX
TypeScriptSoportado directamente en versiones recientes para erasable syntax; type-checking con herramientas aparteEjecución directa; transpila, pero no sustituye el type-checking de tscEjecución directa y deno check integrado
Paquetesnpm, pnpm, Yarnbun install, además de compatibilidad con paquetes npmdeno add, JSR y paquetes npm
APIs de NodeReferencia principalCompatibilidad amplia, pero no totalCompatibilidad creciente; hay APIs y casos que todavía requieren verificación
Seguridad por permisosNo tiene un sandbox de permisos equivalente activado por defectoNo es su propuesta centralPermisos explícitos para archivos, red, entorno y otros recursos
Herramientas integradasEcosistema externo amplioRuntime, gestor de paquetes, runner de tests, bundler y transpilerRuntime, gestor de paquetes, formatter, linter, test runner y type-checker
Ecosistema históricoEl más amplio y probadoCreciente, con énfasis en proyectos TypeScript modernosMás pequeño que Node, con compatibilidad npm cada vez mayor
Mejor encaje típicoProducción conservadora y sistemas con muchas dependenciasAPIs y herramientas donde el rendimiento y la DX importanServicios con enfoque en seguridad, estándares web y tooling integrado

Importante: «ejecutar TypeScript» no equivale a «comprobar tipos». Bun y Node pueden transpilar o eliminar anotaciones, pero la comprobación estática debe seguir formando parte del pipeline cuando se utiliza TypeScript.

3. Node.js: la referencia por ecosistema y previsibilidad

Node.js no necesita ser el runtime más veloz en cada microbenchmark para ser una excelente decisión. Su ventaja central es la combinación de madurez, compatibilidad y conocimiento operativo acumulado.

Ventajas

  • Ecosistema extenso: gran cantidad de librerías, SDKs, integraciones, drivers y herramientas de observabilidad.
  • Compatibilidad: muchos paquetes se desarrollan y prueban primero contra Node.js.
  • Operación conocida: patrones consolidados para contenedores, procesos, profiling, logs, métricas y despliegues.
  • Frameworks backend maduros: Express, Fastify, NestJS, AdonisJS y otros.
  • Opciones de soporte y contratación: es fácil encontrar experiencia en Node.js en equipos y organizaciones.
  • V8: motor con años de optimización para cargas JavaScript de propósito general.

Desventajas

  • Tooling fragmentado: el runtime, el gestor de paquetes, el test runner, el formatter, el linter y el bundler suelen ser herramientas separadas.
  • Arranque y tooling: para scripts pequeños o CLIs, el inicio y el ciclo de desarrollo pueden sentirse más pesados que en Bun.
  • La madurez también implica legado: proyectos antiguos pueden arrastrar CommonJS, dependencias sin mantenimiento o configuraciones complejas.
  • No todo se resuelve con el runtime: la velocidad real depende del framework, del código, de las consultas a base de datos y de la infraestructura.

Cuándo elegir Node.js

Node.js es la opción más conservadora cuando el proyecto depende de librerías críticas, SDKs de proveedores, APM, agentes de seguridad, módulos nativos o integraciones que no puedes reemplazar fácilmente. También es una elección razonable cuando el equipo ya tiene experiencia operando Node y no existe una métrica de negocio que justifique cambiar.

No confundas «más conocido» con «siempre mejor»: si una aplicación nueva puede usar estándares web y tiene dependencias compatibles, Bun o Deno pueden reducir fricción y ofrecer beneficios reales.

4. Bun: rendimiento y herramientas integradas

Bun se construyó con la idea de mejorar tanto la ejecución como la experiencia de desarrollo. Usa JavaScriptCore y está implementado en gran parte en Zig. Incluye runtime, gestor de paquetes, runner de pruebas, transpiler y bundler.

Ventajas

  • Arranque rápido: atractivo para scripts, CLIs, tareas de build y workloads donde se crean procesos con frecuencia.
  • TypeScript y JSX sin configuración adicional: cómodo para desarrollo local y herramientas.
  • Gestor de paquetes integrado: bun install puede acelerar instalaciones en ciertos proyectos y entornos.
  • Servidor HTTP y WebSockets integrados: Bun.serve() ofrece una ruta directa para servicios de red.
  • Compatibilidad con npm y Node: permite ejecutar muchos proyectos y frameworks existentes sin reescribirlos.
  • Buen potencial de rendimiento: sus benchmarks públicos muestran ventajas en algunos escenarios de HTTP, TLS, consultas y WebSockets.

Desventajas y riesgos

  • Compatibilidad no significa identidad: un paquete que depende de un detalle específico de Node, un módulo nativo o una API parcialmente implementada puede comportarse distinto.
  • El framework importa: utilizar Express en Bun no es lo mismo que utilizar el servidor nativo de Bun. El resultado depende de dónde se invierte el tiempo.
  • La operación debe validarse: hay que probar APM, tracing, profiling, workers, despliegues serverless y módulos críticos en la versión concreta elegida.
  • Type-checking separado: la ejecución directa de TypeScript no reemplaza tsc --noEmit ni las verificaciones del pipeline.
  • Menos historial operativo que Node: aunque el proyecto ha madurado, las organizaciones con requisitos estrictos pueden preferir probarlo de forma gradual.

Frameworks y librerías con Bun

Entre las opciones que vale la pena evaluar:

  • Elysia: framework TypeScript diseñado alrededor de Bun, con ergonomía y rendimiento como objetivos centrales.
  • Hono: framework basado en estándares web que soporta Bun, Node.js y Deno, entre otros entornos.
  • Express: muchos proyectos funcionan gracias a la compatibilidad con APIs de Node; se debe probar la aplicación real.
  • NestJS: es posible experimentar con Bun como runtime, pero hay que validar los adaptadores, dependencias, scripts de build y cualquier integración específica. No asumir compatibilidad completa solo porque el proyecto compila.
  • Fastify: el framework está orientado a Node.js; si se pretende ejecutarlo con Bun, hay que validar explícitamente los plugins y las APIs usadas.

Cuándo elegir Bun

Bun es una opción fuerte para una API nueva en TypeScript, herramientas internas, scripts y servicios donde el arranque o el throughput sí tienen valor medible. También es interesante en monorepos para acelerar instalaciones y tareas de desarrollo.

Una estrategia prudente es ejecutar primero tests de compatibilidad y una prueba de carga representativa. Si el servicio depende de un gran número de paquetes nativos o integraciones de producción, empieza con un servicio acotado en lugar de migrar toda la plataforma de golpe.

5. Deno: seguridad, estándares web y experiencia integrada

Deno nació con una postura diferente: permisos explícitos, estándares web y una experiencia coherente para ejecutar, comprobar, probar y formatear código. Su ecosistema ha evolucionado: Deno 2 permite usar una cantidad creciente de paquetes npm y proyectos que originalmente se desarrollaron para Node.js.

Ventajas

  • Permisos explícitos: el código no obtiene automáticamente acceso irrestricto a archivos, red o variables de entorno cuando se ejecuta con el modelo de permisos de Deno.
  • TypeScript directo: no hace falta configurar un transpiler externo para ejecutar TypeScript común.
  • Herramientas integradas: deno fmt, deno lint, deno test y deno check reducen la cantidad de piezas que configurar.
  • Estándares web: APIs como fetch, Request, Response, URL y streams ayudan a compartir patrones entre entornos.
  • Compatibilidad npm en evolución: Deno 2 admite package.json, paquetes npm y más APIs de Node que en sus primeras versiones.
  • Buen rendimiento en algunos workloads HTTP: las versiones recientes han mejorado throughput, arranque y memoria en benchmarks publicados por el equipo.

Desventajas y riesgos

  • Compatibilidad parcial con Node: la cobertura ha avanzado mucho, pero todavía hay APIs, módulos nativos y herramientas que pueden requerir ajustes.
  • Ecosistema menor: hay menos ejemplos, experiencia acumulada y algunas integraciones específicas que en Node.js.
  • Modelo de permisos operativo: es una ventaja de seguridad, pero requiere definir permisos correctamente en scripts, CI y producción.
  • No todas las librerías están diseñadas para estándares web: algunas asumen el sistema de módulos, las rutas o el comportamiento de Node.
  • Hay que probar el despliegue real: especialmente con paquetes nativos, herramientas de build, tracing y librerías que inspeccionan node_modules.

Frameworks y librerías con Deno

  • Hono: funciona en Deno, Bun y Node.js; es una opción interesante para compartir código entre runtimes.
  • Fresh: framework asociado al ecosistema Deno, pensado para aplicaciones web y renderizado en el servidor.
  • Oak: middleware framework inspirado en Koa, tradicional en proyectos Deno.
  • Express y frameworks de Node: Deno 2 puede ejecutar muchos paquetes npm, pero cada aplicación debe validar sus dependencias y comportamiento.

Cuándo elegir Deno

Deno tiene sentido cuando la seguridad por permisos, las APIs web y el tooling integrado son parte importante de la decisión. También puede ser atractivo para servicios nuevos y acotados que usan Hono u otra capa compatible con estándares web.

Para una aplicación que depende de muchas librerías de Node, haz una prueba de compatibilidad antes de convertirlo en la plataforma por defecto. La compatibilidad está avanzando, pero una cifra de cobertura de tests no garantiza que todos los paquetes de tu proyecto funcionen.

6. Frameworks: separar runtime de framework

Uno de los errores más comunes al comparar runtimes es comparar Bun.serve() contra Express, o un servidor HTTP mínimo de Deno contra una aplicación NestJS completa.

Son capas distintas:

  • Runtime: ejecuta JavaScript, gestiona APIs de sistema y proporciona capacidades de red.
  • Servidor HTTP: recibe conexiones y construye respuestas.
  • Framework: agrega routing, middleware, validación, inyección de dependencias y convenciones.
  • Aplicación: suma autenticación, serialización, consultas a datos, reglas de negocio y observabilidad.

Una guía práctica:

Framework / estiloNode.jsBunDenoConsideraciones
node:http / servidor nativoNativoAPIs de Node ampliamente compatibles; validar detallesCompatibilidad node: crecienteComparación de bajo nivel, no de productividad
ExpressNativoMuchos casos funcionan; probar dependenciasCompatible con muchos proyectos vía npm, con validaciónPopularidad no implica el mejor throughput
FastifyNativoValidar plugins y APIs específicasNo es el objetivo principal; validar cuidadosamenteMuy buen punto de referencia en Node
NestJSNativoPosible con validación del adaptador y dependenciasPosible vía compatibilidad Node; revisar cada integraciónLa arquitectura y los módulos pueden pesar más que el runtime
HonoSí, con adaptadorSíSíBuena opción portable basada en estándares web
ElysiaNo es su entorno principalDiseñado para BunNo es su entorno principalInteresante si se decide adoptar Bun de forma explícita
FreshNo es su entorno principalNo es su entorno principalEcosistema DenoMás orientado a aplicaciones web que a ser solo un microframework de API
OakPuede ejecutarse con adaptaciones; no es su focoRevisar compatibilidadTradicional en DenoEvaluar si se busca mantener un proyecto Deno existente

Recomendación: si la portabilidad importa, prioriza APIs web estándar y reduce dependencias que acceden directamente a detalles del runtime. Si necesitas NestJS, plugins específicos de Fastify o un SDK que solo soporta oficialmente Node, no bases la decisión en una prueba con un endpoint vacío.

Para la comparación NestJS / Spring Boot / FastAPI (capa de framework, no de runtime), ver NestJS, Spring Boot y FastAPI.

7. Benchmarks actuales: qué muestran y qué no

Los números que siguen son una muestra de benchmarks públicos consultados en octubre de 2026. No forman una única competición controlada: cada tabla usa cargas, hardware, versiones y configuraciones diferentes. Por eso deben interpretarse dentro de cada prueba, no mezclarse para declarar un ganador absoluto.

7.1 HTTP nativo: endpoint mínimo

La documentación de Bun publica una comparación de un servidor mínimo que devuelve texto. En esa prueba histórica, Bun reporta alrededor de 160 000 requests/s frente a unos 64 000 de Node 16, aproximadamente 2,5 veces más. Es un dato útil para entender el potencial del servidor nativo de Bun, pero no es una comparación con Node moderno ni una API real.

Fuente: Bun — HTTP server benchmarks

7.2 Servidor HTTP y carga realista publicada por Deno

Deno 2.9 publicó una prueba con concurrencia 100, que incluye una respuesta de texto, un cuerpo de 1 MiB y una carga «realworld» que recibe JSON con un bearer token y devuelve JSON. Para la carga realista, el equipo reportó una mejora de 56,8k a 72,4k requests/s frente a Deno 2.8, aproximadamente 1,27×; el uso de memoria reportado pasó de 142 MB a 64 MB.

Esto mide la evolución de Deno entre versiones, no demuestra que Deno sea más rápido que Bun o Node en todas las aplicaciones.

Fuente: Deno 2.9 — Performance

7.3 Comparación publicada por Bun: Express sobre HTTPS

Bun publica una prueba de Express 5.2.1 con TLS 1.3 y bombardier, usando Linux x64 y una CPU AMD EPYC. Las medianas de tres ejecuciones reportadas son:

RuntimeRequests/sRAM máxima
Bun 1.448 243105 MB
Node.js 26.725 181142 MB
Deno 2.9.519 243176 MB

En esa configuración, Bun registra aproximadamente 1,9× el throughput de Node y 2,5× el de Deno. Sin embargo, la tabla proviene del sitio de Bun, y conviene revisar el código de reproducción, las versiones y el comportamiento de las dependencias antes de generalizar.

Fuente: Bun — benchmarks

7.4 Consulta a PostgreSQL: el driver también cambia el resultado

En otra prueba publicada por Bun, se ejecutan consultas a PostgreSQL local: SELECT de 100 filas, 100 consultas concurrentes y 100 000 consultas totales. Se comparan Bun.sql con postgres.js 3.4.9 en Linux x64 sobre AMD EPYC.

Runtime / driverConsultas/sRAM máxima
Bun 1.4 (Bun.sql)20 24380 MB
Deno 2.9.5 (postgres.js)10 406181 MB
Node.js 26.7 (postgres.js)10 000168 MB

Esta prueba no aísla solo el runtime: Bun usa su API SQL integrada, mientras Deno y Node usan postgres.js. Es una comparación del conjunto runtime + cliente de base de datos + configuración, no una prueba pura de ejecución JavaScript.

Fuente: Bun — benchmarks

7.5 Arranque de scripts

Bun documenta un benchmark de un script «Hello World» en Linux con estos valores:

RuntimeTiempo reportado
Bun5,2 ms
Node.js25,1 ms

Es una prueba pequeña y específica de arranque. No equivale al tiempo de arranque de una aplicación que importa NestJS, un ORM, un SDK cloud y varios módulos.

Fuente: Bun Runtime docs

¿Qué conclusión sí podemos sacar?

  • Bun muestra ventajas relevantes en varias pruebas publicadas, especialmente arranque y ciertos escenarios de HTTP y herramientas integradas.
  • Deno ha mejorado mucho en arranque, throughput y consumo de memoria en sus versiones recientes.
  • Node.js continúa siendo competitivo y puede ser la mejor opción global cuando la compatibilidad y la estabilidad de la plataforma pesan más que una diferencia puntual de rendimiento.
  • Los resultados cambian según la carga. El runtime, el framework, el driver de base de datos, TLS, serialización, logging y observabilidad alteran el resultado.
  • Las pruebas de los propios proyectos son útiles, pero no neutrales. Para decidir, hay que reproducirlas y añadir una prueba de la aplicación real.

No uses los números de tablas distintas como si todos se hubieran medido en la misma máquina. Tampoco extrapoles el resultado de un endpoint vacío a una API con consultas, validaciones, autenticación y acceso a servicios externos.

8. Cómo hacer una comparación útil en tu proyecto

En lugar de perseguir un único número, diseña una prueba repetible.

Igualar las condiciones

  1. Usa versiones estables concretas de cada runtime.
  2. Ejecuta el mismo código de negocio y el mismo framework cuando sea compatible.
  3. Mantén iguales el hardware, el sistema operativo, los límites de CPU y memoria y la configuración de red.
  4. Usa la misma base de datos, dataset, pool de conexiones y estrategia de caché.
  5. Prueba con y sin TLS, si TLS forma parte de la arquitectura real.
  6. Repite cada escenario varias veces y reporta medianas y variabilidad.
  7. Separa pruebas de arranque, throughput sostenido y comportamiento bajo picos.

Mide algo más que requests por segundo

MétricaPor qué importa
ThroughputSolicitudes completadas por segundo
Latencia p50, p95 y p99La media puede esconder colas lentas
Memoria residente (RSS)Especialmente con múltiples réplicas
CPU por solicitudÚtil para dimensionar infraestructura
Arranque en fríoImportante para serverless, jobs y CLIs
Errores y timeoutsUn throughput alto no sirve si suben los errores
Estabilidad bajo carga sostenidaNo solo una ráfaga de pocos segundos
Coste por volumen de tráficoImpacto económico, no solo el resultado técnico

Tres escenarios recomendados

Escenario A — HTTP mínimo: permite medir el techo aproximado del servidor y del runtime.

Escenario B — API representativa: incluye routing, validación, serialización, autenticación y una consulta real a la base de datos.

Escenario C — producción simulada: agrega TLS, logging, tracing, límites de CPU/memoria y una carga sostenida con percentiles de latencia.

Para generar carga puedes usar herramientas como oha o bombardier. Revisa que el generador no sea el cuello de botella. La propia documentación de Bun advierte que un cliente de carga demasiado lento puede distorsionar los resultados de un servidor rápido.

Referencia: Bun — Benchmarking

9. Migración: no cambies de runtime solo por una tabla

Si ya tienes una aplicación Node.js, una migración puede costar más que el beneficio.

Checklist antes de cambiar

  • Ejecutar los tests unitarios, de integración y end-to-end en el runtime candidato.
  • Inventariar paquetes que usan node: APIs, CommonJS, addons nativos o acceso directo al sistema.
  • Validar ORM, driver de base de datos, autenticación, hashing, criptografía y SDKs cloud.
  • Probar OpenTelemetry, APM, profiling, logs y métricas.
  • Verificar Docker, health checks, señales de apagado, workers y manejo de procesos.
  • Ejecutar pruebas de carga con el patrón de tráfico real.
  • Definir una estrategia de rollback.
  • Confirmar que las mejoras se mantienen en el entorno donde realmente se desplegará.

Una estrategia de adopción con riesgo limitado

  1. Mantén el runtime actual como referencia.
  2. Elige un servicio pequeño y poco crítico.
  3. Crea una prueba de compatibilidad automatizada.
  4. Mide rendimiento y consumo de recursos con cargas comparables.
  5. Despliega gradualmente y monitorea errores y latencia.
  6. Amplía la adopción solo cuando el beneficio sea observable.

No es necesario migrar toda la organización a un único runtime. Una plataforma puede mantener Node.js para servicios con dependencias maduras y usar Bun o Deno en componentes donde sus ventajas sean claras, siempre que el equipo pueda operar esa diversidad sin aumentar demasiado la complejidad.

10. Matriz de decisión

Si tu prioridad es…Primera opción a evaluarPor qué
Máxima compatibilidad con paquetes y SDKsNode.jsEs la referencia principal del ecosistema
Minimizar riesgo en una plataforma grande ya establecidaNode.jsMenor incertidumbre si todo el tooling ya está probado
Arranque rápido y tooling integradoBunDiseñado para reducir fricción y mejorar arranque
Alto throughput en un servicio nuevoBun y Deno, junto con NodeBenchmark representativo antes de elegir
Seguridad con permisos explícitosDenoEl modelo de permisos es una característica central
Usar APIs web estándar en distintos runtimesDeno o Bun; Hono como framework portableReduce el acoplamiento a APIs específicas de Node
Construir una API con Hono para varias plataformasCualquiera de los tresHono soporta Node, Bun y Deno
Usar NestJS y un gran número de integracionesNode.js como base; probar alternativasCompatibilidad y tooling del proyecto tienen más peso
Scripts, tests, bundling e instalación integradosBun o DenoMenos herramientas separadas para configurar
Adoptar la tecnología con menor curva de cambio para un equipo NodeNode.jsMenos conceptos y diferencias operativas nuevas

Esta matriz no significa que las otras opciones sean incapaces. Señala dónde suele estar la ventaja inicial y qué conviene validar primero.

11. Recomendación final

No existe un ganador universal.

Elegiría Node.js para una plataforma de negocio grande, con muchas dependencias, integraciones de terceros, observabilidad madura y un costo alto por incompatibilidad. Su valor no es solamente la velocidad: es la previsibilidad de todo el ecosistema.

Evaluaría Bun para servicios nuevos en TypeScript, APIs de alto volumen, herramientas de desarrollo y monorepos donde el arranque, la instalación y el rendimiento sean ventajas medibles. Lo adoptaría después de validar las dependencias críticas y el entorno de producción.

Evaluaría Deno cuando el modelo de permisos, las APIs web estándar y la integración de herramientas formen parte importante del diseño. Hono puede ayudar a mantener el código más portable. Antes de migrar una aplicación Node grande, comprobaría las APIs y dependencias exactas.

La decisión de arquitectura correcta es la que equilibra rendimiento, compatibilidad, seguridad, experiencia del equipo, costos operativos y mantenimiento. Si Bun entrega 30 % más throughput en tu carga real y no introduce incompatibilidades, puede ser una gran elección. Si una migración aumenta el riesgo y solo mejora un endpoint sintético, probablemente no compense. Y si Deno resuelve mejor los requisitos de seguridad y despliegue, esa ventaja puede valer más que cualquier ranking de velocidad.

La regla práctica: benchmarkea tu aplicación, no el marketing del runtime.

En esta serie

  1. Node.js: por qué sigue siendo una apuesta sólida
  2. Bun: ¿realmente es más rápido que Node.js?
  3. Deno: seguridad, TypeScript y herramientas
  4. Comparativa final: Node.js vs Bun vs Deno

Lecturas relacionadas

Referencias

Documentación oficial

Cómo leer estas fuentes

Las páginas oficiales son útiles para conocer capacidades, límites de compatibilidad y pruebas reproducibles. Los benchmarks publicados por el propio runtime deben leerse como evidencia de un escenario particular, no como un ranking independiente y definitivo. Antes de una decisión de producción, registra versiones exactas, repite las pruebas y publica la configuración utilizada junto con los resultados.