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-istanbul
test: {
  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',
  },
})