Stop 15 · TestingTopics · 3/8

Vitest

Part of the Frontend Developer Roadmap

In short

If your project uses Vite, Vitest is the natural test runner. It reuses your Vite config, starts fast, and its API looks almost exactly like Jest, so your skills carry over.

A fast, modern test runner built for Vite-based projects, with a Jest-compatible API — increasingly the default choice for new projects using Vite.

The jaadu taps one metro card on a station gate that swings open.

Think of it like this

Metro on the same card

Your metro card already works at every station on the line, no new ticket needed. Vitest uses the same Vite setup, aliases and plugins your app already has, so you skip a whole second configuration.

Watch it happen

Testing debounce with fake timers

Test
debounce
Fake clock
fn

vi.useFakeTimers()

1/6Real timers are swapped for a fake clock the test controls.

The big ideas

What you need to know

Jest-like API

describe, it, expect and mocks all look familiar. jest.fn becomes vi.fn, and jest.mock becomes vi.mock.

Shares your Vite config

Path aliases and plugins from vite.config work in tests too. Add a test block for test-only settings.

Watch by default

Running vitest in a terminal starts watch mode. vitest run does a single pass, which is what CI uses.

Pick an environment

Tests run in Node by default. Set environment to jsdom or happy-dom when testing components that need the DOM.

See it in code

Walk through the code

ts
1// vitest.config.ts2import { defineConfig } from "vitest/config";3export default defineConfig({ test: { environment: "jsdom" } });4 5// debounce.test.ts6import { it, expect, vi } from "vitest";7import { debounce } from "./debounce";8 9it("runs once, 300ms after the last call", () => {10  vi.useFakeTimers();11  const fn = vi.fn();12  const search = debounce(fn, 300);13  search(); search(); search();14  vi.advanceTimersByTime(300);15  expect(fn).toHaveBeenCalledTimes(1);16});

1/4The config sets the jsdom environment. It reuses everything else from your Vite setup.

Fake timers let you skip 300ms instantly instead of really waiting. You'll need the jsdom package installed for that environment setting.

Save yourself the pain

Common mistakes

Oops

Copying jest.fn() and jest.mock() into Vitest files.

Do this instead

Use vi.fn() and vi.mock(), or enable globals: true if you want describe and expect without importing them.

Oops

Using plain vitest in your CI script and hoping it exits.

Do this instead

Use vitest run in CI. It runs every test once and exits, so the pipeline never sits in watch mode.

Your mission

Move a Jest test to Vitest

~20 min

Quick check

What's the Vitest equivalent of jest.fn()?

Go deeper

  1. 1Set up Vitest in a Vite project and write a first test.
  2. 2Compare its speed and config to a Jest setup you've used before.
  3. 3Learn its built-in support for ESM and TypeScript with minimal config.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge