Vitest: Next-Generation Testing Framework
Vitest is a blazing-fast unit testing framework powered by Vite, designed to integrate seamlessly with Vite-based projects. It leverages Vite's dev server internally to transform files during testing, ensuring consistent configuration and performance between development and test environments. Vitest is Jest-compatible, offering a familiar API for assertions (like `expect`) and mocking, alongside out-of-the-box support for ESM, TypeScript, and JSX. The current stable version is 4.1.4, with major releases occurring roughly annually (e.g., v3 in Jan 2025, v4 in Oct 2025) and frequent minor/patch updates. Its key differentiators include shared configuration with Vite, Hot Module Replacement (HMR) for tests, multithreading workers, and a comprehensive ecosystem for component testing across various frameworks like Vue, React, and Svelte. It aims to eliminate the configuration overhead often associated with using other test runners in Vite projects.
Common errors
-
Cannot find module './relative-path' or 'my-aliased-module'
cause Incorrect file path or unresolved module alias from `tsconfig.json`.fixVerify the import path. If using `baseUrl` in `tsconfig.json`, install `vite-tsconfig-paths` and add `tsconfigPaths()` to your Vite/Vitest plugins. -
Failed to terminate worker
cause Occurs when Node.js's `fetch` is used with Vitest's `pool: 'threads'` due to an underlying issue.fixConfigure Vitest to use `pool: 'forks'` or `pool: 'vmForks'` in your `vitest.config.ts` file. -
Cannot mock "./mocked-file.js" because it is already loaded.
cause Attempting to mock a module that has already been loaded by Vitest, often due to `vi.mock` being hoisted or the module being imported in a setup file before mocking.fixEnsure `vi.mock` calls are at the top level of the test file before any imports of the module to be mocked. If the module is loaded in a setup file, consider using `vi.resetModules()` after the initial load or refactor to avoid early loading in the test context. -
SyntaxError: Named export 'X' not found. The requested module 'Y' is a CommonJS module, which may not support all module.exports as named exports.
cause An ESM `import { X } from 'Y'` statement is trying to import a named export `X` from a CommonJS module `Y` that doesn't properly expose it for static analysis.fixTry importing the default export (`import Y from 'Y'`) and access `X` as a property (`Y.X`), or configure `deps.interopDefault: true` in `vitest.config.ts`. -
ReferenceError: require is not defined in ES module scope
cause Attempting to use `require()` within a test file or configuration that is treated as an ES module.fixConvert `require()` calls to ES module `import` statements or dynamic `import()`. Ensure your `package.json` either has `"type": "module"` or uses `.mjs` / `.mts` file extensions for ESM files.
Warnings
- breaking Vitest v4.0 introduced several breaking changes, notably stabilizing Browser Mode which now requires installing separate provider packages (e.g., `@vitest/browser-playwright`). The `context` import location also changed from `@vitest/browser/context` to `vitest/browser`.
- breaking Vitest v3.0 included breaking changes related to V8 code coverage remapping logic, leading to expected changes in coverage reports. The `vitest/execute` entry point was removed, and custom environments no longer use `transformMode` but `viteEnvironment`.
- gotcha Vitest (via Vite) does not automatically respect `baseUrl` or path aliases defined in `tsconfig.json` by default. This can lead to 'Cannot find module' errors for aliased imports.
- gotcha Using Node.js's `fetch` with `pool: 'threads'` can cause 'Failed to terminate worker' errors due to an ongoing issue.
- deprecated The `server` configuration option in `vitest.config.ts` was previously used to define the configuration for the `vite-node` server. While still present, it now primarily manages inlining/externalization mechanisms. `vite-node` itself is no longer a direct dependency, having been replaced by Vitest's internal Module Runner.
- gotcha When importing CommonJS modules that do not explicitly define named exports, Vitest (and Node.js in ESM context) may throw `SyntaxError: Named export 'X' not found`. This happens because dynamic analysis of CommonJS named exports is not always reliable.
Install
-
npm install vitest-dev-server -
yarn add vitest-dev-server -
pnpm add vitest-dev-server
Imports
- defineConfig
import { defineConfig } from 'vite'import { defineConfig } from 'vitest/config' - test, expect, describe, it
const { test, expect } = require('vitest')import { test, expect, describe, it } from 'vitest' - vi
import { vi } from 'vitest' - UserEvent
import userEvent from 'vitest/browser'
Quickstart
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: './vitest.setup.ts',
},
});
// vitest.setup.ts
import '@testing-library/jest-dom';
// src/sum.ts
export function sum(a: number, b: number): number {
return a + b;
}
// src/sum.test.ts
import { expect, test } from 'vitest';
import { sum } from './sum';
describe('sum function', () => {
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
test('adds negative numbers correctly', () => {
expect(sum(-1, -2)).toBe(-3);
});
test('adds zero correctly', () => {
expect(sum(0, 5)).toBe(5);
});
});
// package.json script
// {
// "scripts": {
// "test": "vitest"
// }
// }