Jest

Jest 62,362 needs a compiler, and Next.js 10,514 ships one. next/jest wraps your config so tests run through the same SWC 553,439 transform as the app, loads .env files, stubs CSS and image imports, and derives moduleNameMapper from your tsconfig.json paths.

jest.config.tsJavaScript
const createJestConfig = nextJest({ dir: './' });
const config: Config = {
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
  testMatch: ['<rootDir>/jest-tests/**/*.test.{ts,tsx}'],
};
export default createJestConfig(config);

Install jest, jest-environment-jsdom and the same Testing Library 221,825 packages. dir: './' is the folder holding next.config.ts, which next/jest reads so the transform sees your compiler options, including the React 7,897 Compiler (The React Compiler). jest.setup.ts is one line, import '@testing-library/jest-dom', and the test body is the Vitest 102,989 one without its imports, since Jest injects test and expect as globals. It reports Tests: 1 passed, 1 total in 1.6 s.

Neither runner has a Next.js-specific advantage: both resolve the alias, both handle CSS modules, and both hit the same wall at async Server Components. Jest 30.5.2 is safer when a repository already runs it elsewhere; ESM-only dependencies there often need a transformIgnorePatterns entry. Vitest 5.0.1 is faster to configure and quicker on repeat runs.