ExpressoTS 4.0, el framework TypeScript que planta cara a NestJS
Cada cierto tiempo alguien me escribe con la misma pregunta: "Bezael, tengo que montar una API en Node. ¿Express pelado o NestJS?".
Y la respuesta honesta durante años ha sido incómoda. Express te deja solo: sin DI, sin estructura, sin ciclo de vida. NestJS te da todo eso, pero a cambio de decoradores por todas partes y una curva que a un junior le cuesta semanas.
En medio no había casi nada. Ese hueco es exactamente donde vive ExpressoTS 4.0, publicada el 17 de julio de 2026, casi veinte meses después de la v3, y que por primera vez no parece un proyecto experimental.
Ojo con lo que voy a decir y con lo que no voy a decir. No voy a contarte que esto reemplaza a NestJS. No lo hace. El ecosistema de NestJS es incomparablemente más maduro: integraciones, documentación, gente que ya resolvió tu problema hace dos años. Lo que sí ha cambiado es que ahora existe una alternativa seria para quien quiere estructura sin cargar con todo el peso.
Qué es ExpressoTS y por qué la 4.0 importa
ExpressoTS es un framework TypeScript para backend sobre Node.js. Trae inyección de dependencias con contenedor IoC, routing, middleware, hooks de ciclo de vida, manejo de errores y bootstrap de la aplicación.
Hasta la v3 era, básicamente, "Express con DI y decoradores". Útil, correcto, poco ambicioso.
La 4.0 es otra cosa. Requiere Node.js >= 20.19.0, según las release notes oficiales de la v4.0.0, y trae bloques que hasta ahora te tocaba construir tú o importar de tres librerías distintas.
Dónde queda cada uno, para que no tengas que deducirlo:
| Express | ExpressoTS 4.0 | NestJS | |
|---|---|---|---|
| Inyección de dependencias | No | Sí, contenedor IoC | Sí, contenedor IoC |
| Curva de aprendizaje | Baja | Media | Alta |
| Boilerplate | Mínimo | Moderado | Alto |
| Testing incluido | No | Sí, createTestApp() |
Sí |
| Observabilidad incluida | No | Sí, Studio local | Vía integraciones |
| Madurez del ecosistema | Muy alta | Baja | Muy alta |
Voy a ir a los bloques que de verdad cambian cómo escribes el código.
Interceptors: AOP sin montarte tu propio framework
Los interceptors de ExpressoTS 4.0 aplican cross-cutting concerns —caching, reintentos, transformación de respuestas— con ejecución condicional declarativa: la condición vive en el decorador, no dentro del interceptor.
Este es el titular de la release, y no había visto la idea tan limpia en otros frameworks del ecosistema.
// PerformanceInterceptor viene incluido. CacheInterceptor lo escribes tú.
@UseInterceptors(
PerformanceInterceptor,
whenInterceptor(
(ctx) => ctx.request.headers["x-cache"] === "true",
CacheInterceptor,
),
)
Léelo despacio. El PerformanceInterceptor corre siempre. El CacheInterceptor corre solo si la request trae esa cabecera. No hay un if dentro del interceptor decidiendo si le toca trabajar o no. La condición vive fuera, en la declaración.
Parece un detalle estético. No lo es. La cantidad de código que he visto en producción donde un interceptor empieza con seis líneas de "¿me toca actuar ahora?" es descorazonadora. Ahí es donde nacen los bugs de "en staging cachea y en prod no".
Tienes también unlessInterceptor() para el caso inverso, auto-discovery por decoradores y tres interceptors listos de fábrica: LoggingInterceptor, PerformanceInterceptor y TimeoutInterceptor.
Y para componerlos, dos utilidades que redondean el argumento: pipeInterceptors() los encadena en orden, y combineInterceptors() los lanza en paralelo para trabajo de solo efecto secundario, como logging o métricas.
Eventos tipados con prioridad
El sistema de eventos de ExpressoTS 4.0 combina auto-discovery de handlers, routing condicional y ejecución por prioridad, con tipado end-to-end vía IEventHandler<T>:
@OnEvent(UserCreatedEvent, { priority: 1 })
export class SendWelcomeEmailHandler implements IEventHandler<UserCreatedEvent> {
handle(event: UserCreatedEvent) { /* ... */ }
}
El IEventHandler<UserCreatedEvent> es lo que hace que esto valga la pena. En cuanto alguien cambie la forma del evento, el compilador te avisa en todos los handlers.
Sin eso, un sistema de eventos es una lista de strings mágicos esperando a romperse en el peor momento.
Configuración type-safe y validación pluggable
La configuración se declara con validación y variación por entorno:
export default defineConfig({
database: {
url: Env.string("DATABASE_URL", { required: true }),
},
});
Si falta DATABASE_URL, la aplicación no arranca. No revienta a los veinte minutos en la primera query. Falla en el arranque, que es donde debe fallar.
Y esto conecta con una decisión de diseño que aplaudo: la Smart Validation de v4 usa un registry de adapters pluggable. Soporta class-validator, Zod y Yup. No te casan con una librería.
Si vas a montar algo nuevo con esto, mi recomendación es Zod. Esquema y tipo en la misma declaración, sin decoradores, sin duplicar la forma del dato en dos sitios. Y si te preocupa el coste de tipado en un proyecto grande, ese problema tiene fecha de caducidad: ya conté cómo el compilador de TypeScript reescrito en Go cambia el juego.
Si nunca has llevado Zod más allá de z.object(), en el curso de Zod para TypeScript cubro justo la parte que la gente se salta: transforms, refinements y validación en los bordes del sistema.
ExpressoTS Studio: local, no cloud
ExpressoTS Studio es una plataforma de desarrollo local: no envía tu tráfico a ningún servidor externo. Es la decisión más valiente de la release y merece sección propia.
Te da un dashboard de estado, un mapa de arquitectura generado en vivo desde el grafo de dependencias, un request timeline con spans de OpenTelemetry, logs en directo, inspección de errores, replay de tráfico y una auditoría de seguridad con scoring basada en el tráfico real de tu entorno de desarrollo.
El mapa de arquitectura generado desde el grafo DI es la parte que más me gusta. Documentación de arquitectura que no se queda obsoleta porque nadie la actualiza: se deriva del código.
Y que sea local en vez de SaaS elimina de golpe la conversación con legal antes de empezar.
El resto, en corto
Hay más, y no todo necesita párrafos:
- Lazy-loading de módulos con rutas auto-detectadas desde
@controller()y preload hints (high,medium,low,never). Debería mejorar los cold starts, que en serverless es dinero. - Módulo de testing con
createTestApp()a cero configuración, API fluida para HTTP, snapshot testing y load testing con métricas de percentiles. - Logging de 11 fases: structured logging, transports a fichero, gestión de contexto, consulta de logs y export a Markdown.
- Guards por rol, por permiso y resource-owner, con utilidades de composición.
- Health monitoring en tres capas: middleware pipeline, providers
IHealthChecky dashboard agregado. - Content negotiation RFC 7231: JSON, XML, CSV y YAML.
- Scopes DI personalizados: tenant, transaction, workflow, session. Si haces multi-tenant, esto te ahorra un patrón entero.
- API versioning por URL con el decorador
@Version(). - Errores RFC 7807 (problem details) con exception filters y sugerencias de ruta en los 404.
- Lifecycle hooks:
globalConfiguration(),configureServices(),postServerInitialization(),serverShutdown().
Si vienes de v3: lo que se rompe
Migrar de v3 a v4 tiene tres breaking changes obligatorios:
- Los patrones de DI cambian. Revísalos uno a uno.
- Los lifecycle hooks de
app.tshay que actualizarlos. - Sube el runtime a Node.js >= 20.19.0.
En soporte, el equipo ha sido razonable: según su política publicada, v4.0.0 recibe 24 meses de bugfixes y parches de seguridad. La v3.x tenía 18 meses y los han extendido hasta diciembre de 2026 para que la migración no sea una carrera.
Una migración así es un caso de manual para trabajar con especificación antes que con código: describes el estado destino, listas los puntos de cambio y solo entonces dejas que un agente te ayude a ejecutarlo módulo a módulo. Es la metodología que documenté en el libro de Spec-Driven Development, y funciona especialmente bien cuando el cambio es amplio pero mecánico.
Mi veredicto
ExpressoTS 4.0 no es un juguete. Interceptors condicionales, eventos tipados, scopes DI de tenant y transaction, Studio local: son decisiones de gente que ha sufrido aplicaciones grandes.
¿Lo llevaría a un proyecto crítico, con equipo de quince personas y entrega en tres meses? Todavía no. NestJS tiene ecosistema, integraciones probadas y una comunidad enorme, y eso pesa más que cualquier feature bonita cuando algo te falla un viernes.
¿Lo usaría en un servicio nuevo, un side project o una API interna donde el peso y los cold starts importan? Sin dudarlo.
Instálalo y móntate algo pequeño esta semana:
npx @expressots/cli new my-app
Levanta Studio, mira el mapa de arquitectura que genera del grafo DI y decide con tu propio código delante. Media hora te basta para saber si te encaja. La documentación oficial está sorprendentemente bien para un proyecto de este tamaño.
Y si quieres ver cómo integro frameworks nuevos como este en un flujo de trabajo con agentes de IA —specs primero, implementación asistida, tests de verdad— eso es justo lo que describo en mi stack de IA agéntica y lo que practicamos dentro de Dominicode Labs.
Preguntas frecuentes
¿ExpressoTS 4.0 sustituye a NestJS?
No, y no lo pretende. NestJS tiene un ecosistema mucho más maduro en integraciones, documentación y comunidad. ExpressoTS ocupa el hueco entre Express pelado y NestJS: te da DI, ciclo de vida y estructura con menos boilerplate y una curva más corta. Son opciones distintas, no una sustitución.
¿Qué diferencia hay entre ExpressoTS y Express?
Express es un router HTTP minimalista: no trae inyección de dependencias, ni estructura de proyecto, ni ciclo de vida de aplicación. ExpressoTS se construye sobre esa base y añade contenedor IoC, decoradores para controllers, hooks de ciclo de vida, guards, interceptors y utilidades de testing. Con Express decides tú toda la arquitectura; con ExpressoTS parte ya viene decidida.
¿Qué versión de Node necesito para ExpressoTS 4.0?
Node.js 20.19.0 o superior, según las release notes oficiales de la v4.0.0 (17 de julio de 2026). Es un breaking change respecto a v3, así que verifica el runtime de tu entorno de despliegue antes de migrar.
¿ExpressoTS Studio envía mis datos a la nube?
No. Studio es una plataforma de desarrollo local. El dashboard, el mapa de arquitectura, el request timeline con spans OpenTelemetry, los logs y la auditoría de seguridad funcionan sobre el tráfico de tu entorno de desarrollo, en tu máquina.
¿Puedo usar Zod para validar en ExpressoTS 4.0?
Sí. La Smart Validation de v4 funciona con un registry de adapters pluggable que soporta class-validator, Zod y Yup. Puedes elegir la librería que ya uses en el resto del proyecto.
¿Cuánto tiempo tengo para migrar desde v3?
El soporte de v3.x se ha extendido hasta diciembre de 2026. La v4.0.0 recibe 24 meses de bugfixes y parches de seguridad desde su publicación en julio de 2026. Tienes margen para planificar la migración sin prisas.
¿Qué se rompe al migrar de ExpressoTS v3 a v4?
Tres cosas: los patrones de inyección de dependencias cambian y hay que revisarlos uno a uno, los lifecycle hooks de app.ts necesitan actualizarse, y el runtime debe subir a Node.js 20.19.0 o superior.
¿ExpressoTS 4.0 sirve para serverless?
Es uno de los escenarios donde mejor encaja. El lazy-loading de módulos carga solo lo necesario en cada invocación, con preload hints (high, medium, low, never) para afinar qué se precarga, lo que ayuda con los cold starts. Súmale que el core es ligero comparado con alternativas más pesadas del ecosistema.
Por Bezael Pérez — Developer senior con más de 15 años de experiencia y fundador de Dominicode.
