Vitest Cheatsheet
Plugins
Use this Vitest reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
How Vitest Uses Vite Plugins
Vitest runs on top of Vite, so any Vite plugin works inside the test run. Plugins are declared in the top-level plugins array of vite.config.ts / vitest.config.ts.
import { defineConfig } from 'vitest/config' import react from '@vitejs/plugin-react' import tsconfigPaths from 'vite-tsconfig-paths' export default defineConfig({ plugins: [ react(), tsconfigPaths(), ], test: { globals: true, environment: 'jsdom' }, })
Common Plugins for Testing
@vitejs/plugin-react / @vitejs/plugin-vue
Required for JSX/TSX transformation in component tests.
npm install -D @vitejs/plugin-react
import react from '@vitejs/plugin-react' plugins: [react()]
For Solid, Svelte, etc.:
npm install -D vite-plugin-solid npm install -D @sveltejs/vite-plugin-svelte
vite-tsconfig-paths
Resolves TypeScript path aliases (@/components/...) without duplicating them in Vite config.
npm install -D vite-tsconfig-paths
import tsconfigPaths from 'vite-tsconfig-paths' plugins: [tsconfigPaths()]
@vitest/ui
Interactive test runner in the browser with test tree, source, coverage overlay.
npm install -D @vitest/ui
vitest --ui
# opens http://localhost:51204/__vitest__/// No plugin config needed — enabled via CLI flag@vitest/coverage-v8 / @vitest/coverage-istanbul
Code coverage providers:
npm install -D @vitest/coverage-v8
# or
npm install -D @vitest/coverage-istanbultest: {
coverage: { provider: 'v8' }
}Browser Mode (@vitest/browser-playwright)
Runs tests inside a real browser via Playwright or WebdriverIO. Vitest 4 splits providers into packages (@vitest/browser-playwright, @vitest/browser-webdriverio, @vitest/browser-preview) and replaces the removed browser.name with browser.instances:
npm install -D @vitest/browser-playwright playwright npx playwright install chromium
import { playwright } from '@vitest/browser-playwright' test: { browser: { enabled: true, provider: playwright(), headless: true, instances: [{ browser: 'chromium' }], } }
unplugin-auto-import
Auto-import Vitest globals (like describe, it, expect) without explicit imports:
npm install -D unplugin-auto-import
import AutoImport from 'unplugin-auto-import/vite' plugins: [ AutoImport({ imports: ['vitest'], dts: './src/auto-imports.d.ts', }), ]
Now you can write tests without import { describe, it, expect } from 'vitest'.
vite-plugin-checker
Type-check and lint in parallel with tests using vite-plugin-checker:
npm install -D vite-plugin-checker
import checker from 'vite-plugin-checker' plugins: [ checker({ typescript: true, eslint: { lintCommand: 'eslint "./src/**/*.{ts,tsx}"' }, }), ]
In test mode, checker runs in the background — type errors appear in the terminal alongside test output.
@storybook/addon-vitest
Run Storybook stories as Vitest tests (Storybook 9+; supersedes @storybook/experimental-addon-test and the old experimental plugin):
npx storybook add @storybook/addon-vitest
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin' plugins: [storybookTest({ configDir: '.storybook' })]
// Button.stories.ts — plays run as vitest tests automatically export const Primary = { args: { label: 'Click me' }, play: async ({ canvasElement }) => { const canvas = within(canvasElement) await userEvent.click(canvas.getByRole('button')) expect(canvas.getByText('clicked')).toBeVisible() }, }
vite-plugin-istanbul
Adds Istanbul instrumentation at the Vite transform level (alternative to the coverage provider approach):
npm install -D vite-plugin-istanbul
import istanbul from 'vite-plugin-istanbul' plugins: [ istanbul({ include: 'src/*', exclude: ['node_modules', 'test/'], extension: ['.js', '.ts', '.vue'], requireEnv: true, // only instrument when VITE_COVERAGE=true }), ]
vite-plugin-mock (MSW Alternative)
Simple in-process request mocking via Vite plugin (not a Service Worker):
npm install -D vite-plugin-mock
import { viteMockServe } from 'vite-plugin-mock' plugins: [ viteMockServe({ mockPath: 'mock', // folder with mock files enable: true, }), ]
Writing a Custom Vitest Plugin
Vitest plugins are Vite plugins with optional configureVitest / vitestConfigSchema extensions.
// my-vitest-plugin.ts import type { Plugin } from 'vite' export function myVitestPlugin(): Plugin { return { name: 'my-vitest-plugin', // Standard Vite hooks — run during test transform transform(code, id) { if (id.endsWith('.test.ts')) { // transform test files return code } }, // Vitest-specific hook (Vite plugin context) configureServer(server) { // access the Vite dev server }, } }
Vitest-Specific Reporter Plugin
import type { Reporter } from 'vitest' export class MyReporter implements Reporter { onInit(ctx: Vitest) { console.log('Tests starting...') } onTaskUpdate(packs) { for (const [id, result] of packs) { if (result?.state === 'fail') { console.error(`FAILED: ${id}`) } } } onFinished(files, errors) { console.log(`Done. Files: ${files.length}`) } }
// vitest.config.ts import { MyReporter } from './my-reporter' export default defineConfig({ test: { reporters: [new MyReporter()], }, })
Plugin Execution Order
Plugins execute in order. Use enforce: 'pre' or enforce: 'post' to control position:
{
name: 'run-first',
enforce: 'pre',
transform(code) { /* ... */ }
}Environment Plugin (Custom Environment)
// my-env.ts import type { Environment } from 'vitest' export default <Environment>{ name: 'my-env', transformMode: 'ssr', async setup() { // setup global APIs return { teardown() { // cleanup }, } }, }
// vitest.config.ts export default defineConfig({ test: { environment: './my-env.ts', }, })