Vitest vs Jest en 2026: por qué Vitest ganó la partida
Vitest ha desplazado a Jest como runner por defecto en la mayoría de proyectos nuevos. Analizamos las razones técnicas reales, no solo la novedad, y cuándo Jest sigue siendo la opción correcta.
Durante años, si empezabas un proyecto JavaScript y necesitabas tests, la respuesta por defecto era Jest. Era el runner que traía Create React App, el que usaba media industria, el que tenía más plugins y más respuestas en Stack Overflow. En 2026 esa respuesta automática ha cambiado: la mayoría de proyectos nuevos —y un número creciente de frameworks— arrancan con Vitest. No es una moda pasajera ni un capricho de los primeros adoptantes: es una consecuencia directa de cómo ha cambiado el tooling de JavaScript en los últimos años.
Este artículo no es “Vitest es más nuevo, así que es mejor”. Es una revisión de qué problema técnico concreto resuelve Vitest que Jest no puede resolver sin fricción, y de en qué situaciones Jest sigue siendo la opción sensata.
El problema de fondo: Jest nació en un mundo sin ESM ni Vite
Jest se diseñó en la era de CommonJS y Babel como transformador universal. Para ejecutar tests, Jest necesita interceptar cada require/import, transformarlo (normalmente vía Babel o ts-jest) y ejecutarlo en su propio entorno simulado de módulos. Funciona, pero implica mantener una capa de transformación paralela a la que ya usa tu bundler de desarrollo. Si tu aplicación usa Vite, Webpack o cualquier herramienta moderna, acabas con dos pipelines de compilación distintos: uno para servir la app y otro para ejecutar los tests, cada uno con su propia configuración de alias, plugins y resolución de módulos.
Ese desajuste es la raíz de buena parte de los dolores de cabeza clásicos de Jest: alias de rutas que funcionan en la app pero no en los tests, paquetes ESM-only que Jest no sabe transformar sin configuración adicional, diferencias sutiles entre cómo Vite resuelve un import y cómo lo hace Babel.
Vitest ataca el problema desde el otro extremo: en vez de construir un pipeline de transformación propio, reutiliza directamente la configuración de Vite. Si tu app ya se compila y sirve con Vite, Vitest ejecuta los tests con exactamente esa misma configuración: mismos alias, mismos plugins, misma resolución de módulos, mismo soporte nativo de ESM y TypeScript sin pasos de compilación intermedios. No es una integración añadida a posteriori; es la razón de ser de la herramienta.
Velocidad: no es solo “se siente más rápido”
La ventaja de velocidad de Vitest no es un efecto placebo. Tiene tres causas técnicas concretas:
- Transformación bajo demanda con esbuild. Vite (y por tanto Vitest) usa esbuild para transformar TypeScript y JSX, que es órdenes de magnitud más rápido que Babel al estar escrito en Go y no aplicar el árbol de plugins completo de Babel en cada archivo.
- Watch mode con grafo de dependencias real. Cuando cambias un archivo, Vitest solo re-ejecuta los tests cuya cadena de imports realmente depende de ese archivo, aprovechando el mismo grafo de módulos que usa Vite en desarrollo. Jest, sin esa información de dependencias en tiempo real, tiende a re-ejecutar de forma más conservadora.
- Aislamiento por worker más ligero. Vitest ejecuta los archivos de test en workers (
vitestusatinypoolinternamente) reutilizando el mismo proceso de transformación en caliente, mientras que el modelo de aislamiento por defecto de Jest recompila y reinstancia módulos con más overhead entre archivos.
En la práctica, para una suite mediana con cientos de archivos de test, esto se traduce en arranques en frío notablemente más rápidos y watch mode casi instantáneo. Las cifras concretas de “X veces más rápido” varían mucho según el proyecto, el tamaño de la suite y cuánta transformación de TypeScript/JSX hay de por medio, así que conviene desconfiar de cualquier benchmark que prometa un múltiplo universal: mídelo en tu propio proyecto antes de citarlo como argumento.
ESM nativo: el punto donde Jest sigue sufriendo más
El soporte de ECMAScript Modules en Jest ha mejorado, pero sigue siendo el flag --experimental-vm-modules de Node.js, con matices y casos límite documentados que no siempre son intuitivos, especialmente cuando entran en juego paquetes que solo publican ESM (exports en su package.json sin variante CommonJS) o dependencias con import.meta. Vitest, al construirse sobre Vite, trata ESM como el caso normal en vez de como una extensión: no hay flag experimental que activar.
Esto importa cada vez más porque el ecosistema npm lleva años migrando hacia “ESM-only” para paquetes nuevos. Cuantas más dependencias de tu proyecto sean ESM-only, más fricción vas a notar en Jest y menos en Vitest.
API compatible: por qué migrar no es reescribir toda la suite
Uno de los factores que más ha acelerado la adopción de Vitest es que su API es, en gran medida, compatible con la de Jest: describe, it, expect, beforeEach, mocks con vi.fn() en vez de jest.fn(). La mayoría de asserts de Jest funcionan igual en Vitest, y existen guías de migración que en muchos proyectos se reducen a cambiar imports y algunos nombres de API de mocking. Eso no significa que la migración sea automática ni cero esfuerzo: proyectos con configuración compleja de transformadores personalizados, mocks a nivel de módulo muy específicos de Jest, o snapshot serializers particulares, requieren revisión manual.
// jest
import { describe, it, expect, jest } from '@jest/globals';
describe('formatPrice', () => {
it('formatea en euros', () => {
const spy = jest.fn();
expect(formatPrice(10)).toBe('10,00 €');
});
});
// vitest — mismo test, API casi idéntica
import { describe, it, expect, vi } from 'vitest';
describe('formatPrice', () => {
it('formatea en euros', () => {
const spy = vi.fn();
expect(formatPrice(10)).toBe('10,00 €');
});
});
Testing de componentes: Browser Mode frente a jsdom
Otra diferencia que ha pesado en la decisión de muchos equipos frontend es el Browser Mode de Vitest, que llegó a estabilidad plena como funcionalidad de primera clase del proyecto. En vez de simular el DOM con jsdom o happy-dom —aproximaciones razonables pero imperfectas de cómo se comporta un navegador real—, Browser Mode ejecuta los tests dentro de un navegador de verdad (vía Playwright o WebdriverIO como proveedor), con el mismo runner, configuración y watch mode que usas para el resto de tests unitarios.
La diferencia no es cosmética: jsdom no implementa layout real, getBoundingClientRect de forma fiel, ni buena parte de las APIs de CSS moderno. Para componentes con lógica de interacción compleja (drag and drop, animaciones condicionadas al layout, media queries), un navegador real elimina una categoría entera de falsos positivos y falsos negativos que jsdom no puede resolver por diseño. Jest, al no tener un concepto equivalente integrado de forma nativa, depende de librerías externas o de delegar esa capa a otra herramienta.
Adopción real: no es solo percepción
Los datos de adopción respaldan lo que se observa en el día a día: la encuesta State of JavaScript 2025 sitúa a Vitest como una de las herramientas de testing con más crecimiento en satisfacción y uso, mientras la satisfacción de Jest muestra una tendencia a la baja. Angular, uno de los frameworks históricamente más conservadores en su elección de herramientas de testing, anunció Vitest como opción por defecto a partir de Angular 21, sustituyendo a Karma. Nuxt, SvelteKit y Astro también recomiendan o integran Vitest de forma nativa en sus plantillas.
Esto no convierte a Jest en una herramienta obsoleta: Jest sigue teniendo una base instalada enorme, mantenimiento activo bajo la OpenJS Foundation y un ecosistema de plugins más maduro en algunos nichos concretos (por ejemplo, ciertos entornos de testing de React Native).
Cuándo Jest todavía tiene sentido
Sería deshonesto presentar esto como un caso cerrado. Hay escenarios reales donde quedarse en Jest —o incluso elegirlo para un proyecto nuevo— es la decisión correcta:
- Proyectos legacy grandes con configuración de Jest muy madura. Si tienes cientos de archivos de test, transformadores personalizados y
moduleNameMappercomplejo funcionando de forma estable, el coste de migración puede no compensar el beneficio de velocidad a corto plazo. Migra quirúrgicamente, no como proyecto de fin de semana. - React Native. El ecosistema de testing de React Native sigue construido en gran parte alrededor de Jest, y el soporte de Vitest en ese entorno es más reciente y menos probado en producción a gran escala.
- Equipos con inversión fuerte en snapshot testing y matchers específicos de Jest que no tienen equivalente directo o requieren reescritura no trivial.
- Cuando el proyecto no usa Vite ni se beneficia de ESM nativo, y la superficie de configuración actual de Jest ya está resuelta y estable: el ahorro de velocidad puede no justificar el esfuerzo de migración si el equipo no sufre ese dolor hoy.
La recomendación práctica para 2026: en un proyecto nuevo, especialmente si ya usas Vite, Astro, SvelteKit o Nuxt, empieza con Vitest por defecto. En un proyecto existente con Jest funcionando sin fricción real, no migres solo por seguir la tendencia — migra cuando el dolor de mantenimiento del pipeline dual empiece a costar más tiempo de ingeniería que la propia migración.
Si vas a construir tests end-to-end además de unitarios, conviene entender también cómo encaja Vitest con una suite de Playwright en el mismo proyecto, y qué papel juega cada capa dentro de una estrategia de testing coherente — algo que tratamos a fondo al revisar si la pirámide de testing clásica sigue teniendo sentido en 2026.
Artículos relacionados
Mutation testing: la técnica que revela tests que no prueban nada
Un test puede pasar, tener cobertura del 100% y no detectar nada si el código se rompe. Mutation testing introduce bugs deliberados para comprobarlo. Así funciona en el ecosistema JavaScript y TypeScript.
Bun vs Node.js vs Deno en 2026: qué runtime elegir y por qué
Tres runtimes de JavaScript, tres filosofías distintas. Esto es lo que dicen los datos (varios, no uno solo) y cuándo cada uno gana de verdad.
TypeScript 6 y el camino a TypeScript 7: la guía de la migración al compilador nativo
TypeScript 6 fue la última versión escrita en TypeScript; TypeScript 7 reescribe el compilador en Go y multiplica la velocidad por diez. Esto es lo que cambia y cómo prepararte.