DEV Community

Alex Spinov
Alex Spinov

Posted on

Vitest Has a Free API: The Test Runner That Makes Jest Feel Slow

Jest takes 30 seconds to start. Vitest takes 300 milliseconds. That's not an exaggeration.

What Is Vitest?

Vitest is a Vite-native test runner that's API-compatible with Jest but dramatically faster. Same describe, it, expect — but powered by Vite's transform pipeline and native ESM.

import { describe, it, expect } from 'vitest'

describe('math', () => {
  it('adds numbers', () => {
    expect(1 + 1).toBe(2)
  })

  it('handles async', async () => {
    const result = await fetchData()
    expect(result).toMatchSnapshot()
  })
})
Enter fullscreen mode Exit fullscreen mode

If you know Jest, you know Vitest. The API is nearly identical.

Why Vitest Is Faster

1. No transform overhead — Vitest reuses Vite's transform pipeline. Your TypeScript, JSX, CSS modules — all handled by the same transforms your dev server uses.

2. Watch mode is instant — Vitest knows which tests to re-run based on the module graph. Change a file → only affected tests run.

3. Thread-based parallelism — Tests run in worker threads with full isolation but minimal overhead.

Features Jest Doesn't Have

// In-source testing — tests live in the source file
// my-module.ts
export function add(a: number, b: number) { return a + b }

if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('adds', () => { expect(add(1, 2)).toBe(3) })
}

// Type testing
import { expectTypeOf } from 'vitest'
expectTypeOf(add).toBeFunction()
expectTypeOf(add).parameter(0).toBeNumber()

// Browser mode — run tests in a real browser
// vitest.config.ts
export default { test: { browser: { enabled: true, name: 'chromium' } } }

// Benchmarking
import { bench, describe } from 'vitest'
describe('sort', () => {
  bench('Array.sort', () => { [3,1,2].sort() })
  bench('custom sort', () => { customSort([3,1,2]) })
})
Enter fullscreen mode Exit fullscreen mode

Migration from Jest

# Most Jest tests work without changes
npx vitest run

# Config migration
# jest.config.js → vitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
  test: {
    globals: true,        // jest-like global APIs
    environment: 'jsdom', // browser environment
    coverage: { provider: 'v8' },
  }
})
Enter fullscreen mode Exit fullscreen mode

Benchmark: Vitest vs Jest

On a 500-test TypeScript project:

  • Jest: 45s cold start, 12s watch re-run
  • Vitest: 3s cold start, 0.5s watch re-run
npm install -D vitest
Enter fullscreen mode Exit fullscreen mode

Building JavaScript apps? Check out my developer tools or email spinov001@gmail.com.

Top comments (0)