Full-stack TypeScript en 2025: lo bueno, lo regular, lo malo
Índice de contenidos
Actualizado: 2026-05-03
Durante varios años me resistí a la idea de full-stack TypeScript. Venía de arquitecturas con Go o Python en el backend y TypeScript solo en el frontend, y la idea de unificar me parecía una concesión por conveniencia. En los últimos dos años he trabajado en varios proyectos donde el stack es íntegramente TypeScript, y tengo opiniones más matizadas que las de entonces.
El objetivo de este post no es convencer a nadie de que adopte full-stack TypeScript, ni desaconsejarlo, sino ofrecer un repaso honesto de qué he visto funcionar, qué sigue siendo problema y en qué tipo de proyecto la elección tiene sentido.
Puntos clave
- El modelo de datos compartido y herramientas como tRPC eliminan la capa de generación de código entre frontend y backend.
- Los frameworks modernos (Next.js App Router, Remix, SvelteKit) han difuminado la línea cliente-servidor de manera que simplifica proyectos de tamaño mediano.
- El ecosistema de testing sigue fragmentado; Vitest es el mejor punto de partida para proyectos nuevos.
- Para servicios CPU-bound o con requisitos de latencia estricta, Go o Rust siguen siendo más apropiados que Node.
- La elección tiene sentido en productos pequeños a medianos con equipos pequeños e iteración rápida.
Lo bueno
La ventaja más inmediata es el modelo de datos compartido. Cuando el mismo tipo User o Product vive en frontend y backend, y no tienes que escribirlo dos veces ni sincronizarlo con un generador externo, el coste cognitivo baja y los errores por desalineación desaparecen. Es de esas cosas que no aprecias hasta haberlas vivido, porque la alternativa (OpenAPI, Protobuf, duplicación manual) funciona, pero añade un paso constante de mantenimiento.
Herramientas como tRPC han convertido esto en algo mucho más que el tipo compartido. Con tRPC, un procedimiento en el backend es automáticamente una función tipada en el frontend, con autocompletado completo, validación en serialización y deserialización, y sin capa de generación de código externa.
La segunda ventaja real es el ecosistema de frameworks que asume full-stack desde el principio. Next.js con App Router, Remix (ahora fusionado con React Router), SvelteKit, Nuxt: todos están diseñados para que escribir una función en el servidor y consumirla desde el cliente sea trivial. Esta integración se ha vuelto tan buena que la línea entre frontend y backend se ha difuminado, y en proyectos de tamaño pequeño a mediano eso simplifica mucho.
Tercero, la calidad del tipado ha mejorado mucho con TypeScript 5.x: inferencia más potente, tipos condicionales más expresivos, constantes. El tipo derivado de un esquema Zod, por ejemplo, suele ser más expresivo que lo que escribirías a mano, y la validación en tiempo de ejecución y la verificación en tiempo de compilación usan la misma fuente de verdad.
Lo regular
Hay zonas donde el balance es más ambiguo:
- Rendimiento del backend en Node.js: razonable para servicios IO-bound, pero no brillante para servicios CPU-bound o con latencia predecible estricta. La aparición de Bun y Deno ha puesto presión saludable, y Bun especialmente tiene características muy interesantes (rendimiento de startup, ecosistema más ligero), pero la mayoría de proyectos reales siguen en Node por compatibilidad npm y soporte empresarial. Vale la pena revisar Deno 2.0 para proyectos nuevos.
- Gestión de dependencias: npm y pnpm han estabilizado mucho, pero tener 1.200 paquetes en node_modules en un proyecto modesto sigue siendo lo normal. Cada ataque a la cadena de suministro en paquetes populares recuerda que esta es una superficie grande.
- Tamaño del bundle frontend: con React Server Components y mejor tree-shaking ha mejorado, pero es muy fácil que un proyecto se hinche sin darse cuenta hasta que el tiempo de carga lo hace evidente.
Lo malo
Hay cosas que siguen siendo francamente problemáticas:
- El ecosistema de testing está fragmentado. Vitest se ha estabilizado como alternativa seria a Jest y es claramente mejor para proyectos nuevos, pero migrar proyectos grandes sigue siendo un dolor. Las librerías de mocking son numerosas y ninguna se ha convertido en estándar claro.
- La fricción entre frontend y backend en servicios realmente grandes vuelve a aparecer. Cuando el proyecto crece lo suficiente, lo que parecía una sola base de código se parte en dos o tres, y el beneficio de compartir tipos se reduce.
- La experiencia con TypeScript en librerías de terceros sigue siendo desigual. Algunas librerías están excelentemente tipadas; otras publican tipos incompletos o incorrectos. Cuando te topas con una definición mala, arreglarlo implica forkear, escribir declaraciones locales o aguantar con
any. - La compilación sigue pesando. Un proyecto TypeScript grande compila más lento que el equivalente en Go o Rust. Las mejoras en TypeScript 5.x (project references, incremental) han aliviado pero no eliminado el problema.
Cuándo tiene sentido
Después de probar varias configuraciones, mi recomendación es:
- Buena elección: proyectos de producto de tamaño pequeño a mediano donde el equipo es pequeño, la iteración es rápida y la cercanía entre frontend y backend aporta. SaaS B2B, dashboards internos, herramientas admin, productos en etapa temprana.
- Elección menos clara: sistemas con componentes heterogéneos, donde el backend hace trabajo pesado (procesamiento de datos, cálculos complejos, streaming de tiempo real), o donde varios equipos independientes trabajan en el mismo sistema.
- Mala elección: cuando el requisito real es rendimiento sostenido alto, bajo uso de memoria o despliegue en entornos muy restringidos. Ahí hay lenguajes diseñados para eso.
Lo que viene
Espero ver consolidación más que revolución. Bun va a seguir presionando a Node, lo cual es bueno. Los frameworks como Next.js van a seguir difuminando la línea entre cliente y servidor. La tipificación automática de esquemas de base de datos (à la Drizzle ORM) va a extenderse. Y el ecosistema de herramientas como tRPC va a tener alternativas maduras en otras plataformas.
Full-stack TypeScript ha ganado un hueco legítimo y probablemente va a mantenerlo durante años. No es la solución universal, pero para una franja real del mercado es una elección razonable que, bien implementada, da resultados muy buenos.