Jest was revolutionary. But it's slow — cold starts take seconds, watch mode re-runs too much, and configuring TypeScript/ESM support feels like solving a puzzle. Vitest runs on Vite and delivers the same API with 10x faster execution.
What Vitest Gives You for Free
- Vite-powered — instant HMR for tests, shared config with your app
-
Jest-compatible API —
describe,it,expect,vi.mock()all work -
TypeScript/ESM native — no
ts-jest, no Babel, no config - In-source testing — write tests next to your code
- UI mode — visual test explorer in the browser
- Code coverage — built-in with c8 or istanbul
- Benchmark mode — performance testing built in
Quick Start
npm install -D vitest
// package.json
{
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui",
"coverage": "vitest run --coverage"
}
}
No config file needed if you already use Vite. Vitest reads vite.config.ts automatically.
Writing Tests (Familiar Jest API)
// math.test.ts
import { describe, it, expect } from 'vitest';
import { calculateTotal } from './math';
describe('calculateTotal', () => {
it('sums items with tax', () => {
const items = [
{ price: 10, quantity: 2 },
{ price: 5, quantity: 3 }
];
expect(calculateTotal(items, 0.1)).toBe(38.5);
});
it('handles empty cart', () => {
expect(calculateTotal([], 0.1)).toBe(0);
});
});
Mocking (Same as Jest, Cleaner Syntax)
import { describe, it, expect, vi } from 'vitest';
import { fetchUser } from './api';
import { db } from './database';
// Mock a module
vi.mock('./database', () => ({
db: {
users: {
find: vi.fn()
}
}
}));
describe('fetchUser', () => {
it('returns user from database', async () => {
vi.mocked(db.users.find).mockResolvedValue({ id: 1, name: 'Alice' });
const user = await fetchUser(1);
expect(user.name).toBe('Alice');
expect(db.users.find).toHaveBeenCalledWith(1);
});
});
Snapshot Testing
import { it, expect } from 'vitest';
import { render } from '@testing-library/react';
import { UserCard } from './UserCard';
it('renders user card correctly', () => {
const { container } = render(
<UserCard name="Alice" role="Admin" />
);
expect(container).toMatchSnapshot();
});
Benchmark Mode (Built-In Performance Testing)
// sort.bench.ts
import { bench, describe } from 'vitest';
describe('sorting', () => {
const data = Array.from({ length: 10000 }, () => Math.random());
bench('Array.sort', () => {
[...data].sort((a, b) => a - b);
});
bench('custom quicksort', () => {
quickSort([...data]);
});
});
vitest bench
Speed Comparison
| Metric | Vitest | Jest |
|---|---|---|
| Cold start | ~300ms | ~3s |
| Watch re-run | ~50ms | ~500ms |
| 1000 tests | ~2s | ~15s |
| TypeScript | Native | Needs ts-jest |
| ESM | Native | Experimental |
| Config needed | 0 lines* | 20+ lines |
*When using with Vite
UI Mode (Visual Test Explorer)
vitest --ui
Opens a browser dashboard showing all tests, their status, execution time, and code coverage — with real-time updates as you edit code.
Migration From Jest
Most Jest tests work with zero changes:
- import { jest } from '@jest/globals';
+ import { vi } from 'vitest';
- jest.fn()
+ vi.fn()
- jest.mock('./module')
+ vi.mock('./module')
That's it for 90% of test suites.
The Verdict
Vitest is Jest for the Vite era. Same familiar API, dramatically faster, TypeScript-native, and zero config when using Vite. If you're starting a new project or tired of Jest's cold starts, Vitest is the obvious choice in 2026.
Need help building production web scrapers or data pipelines? I build custom solutions for startups and enterprises. Reach out: spinov001@gmail.com
Check out my awesome-web-scraping collection — 400+ tools for extracting web data.
Top comments (0)