✅ Testing & Calidad 🟨 JavaScript & TypeScript

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.

📅 19 de enero de 2026 ⏱️ 8 min de lectura ✍️ Equipo ProgramacionWebs

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:

  1. 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.
  2. 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.
  3. Aislamiento por worker más ligero. Vitest ejecuta los archivos de test en workers (vitest usa tinypool internamente) 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 moduleNameMapper complejo 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.

Compartir