C.W.K.
Stream
Lesson 03 of 03 · published

Vitest, Playwright, Jest, Cypress — When Each

~16 min · foundations, tool-selection, stack

Level 0Test Curious
0 XP0/32 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"Picking testing tools should take 30 minutes, not three sprints."

The Working Stack (2026)

If you're starting a new web project today, the answer is short:

  • Vitest for unit, component, and integration tests.
  • React Testing Library (RTL) layered on top of Vitest for component tests.
  • MSW for network mocking — works inside Vitest tests and Playwright tests both.
  • Playwright for E2E tests.

That's the whole stack. Four packages, two test runners (Vitest + Playwright run in separate processes for different purposes). It's not the only valid stack — but it's the default for a reason, and the rest of this quest assumes it.

What About Jest?

Jest is still excellent software. If you're maintaining a large project that already runs on Jest, the migration cost to Vitest may not be worth it — Vitest's API is mostly Jest-compatible by design, but config quirks and edge cases catch you. For new projects, though, Vitest wins on three axes:

  • Speed: Vitest reuses Vite's transform pipeline. First test runs in seconds; subsequent runs are sub-second.
  • ESM-native: Jest's CommonJS heritage makes modern ESM modules awkward. Vitest is ESM-first.
  • Same toolchain as your app: if you already use Vite (and Next.js, Remix, SvelteKit, Astro all use Vite or Vite-like tools), Vitest reuses your config.

What About Cypress?

Cypress is still a fine tool. It pioneered a lot of modern E2E ergonomics — auto-wait, time-travel debugging, dev-time UI. But Playwright has matched or exceeded those features over the last three years and added cross-browser real testing (Chromium + Firefox + WebKit) where Cypress runs only on Chromium-family browsers. If you have a Cypress suite that works, keep it. If you're choosing fresh, Playwright is the answer.

Don't mix E2E tools unless you have a specific reason. A team running both Cypress and Playwright is paying twice for the same thing in maintenance, flakiness investigation, and onboarding. Pick one, commit, and don't re-litigate every quarter.

The Decision in Three Questions

  1. New project, no existing tests? Vitest + Playwright. Done.
  2. Existing Jest suite, considering migration? Estimate the cost. If the suite is small or you're already rewriting half of it, migrate. If it's huge and stable, stay on Jest — both will be supported for years.
  3. Existing Cypress suite? Migrate only if you need cross-browser coverage or you're hitting Cypress-specific friction. Otherwise stay.

What Each Tool Is NOT

Vitest isn't a browser. It runs in Node with a DOM emulator (happy-dom or jsdom). Real CSS, real layout, real network — that's Playwright. Playwright isn't a fast inner loop. A Playwright test that takes 3 seconds is 50× slower than a Vitest test that takes 60 ms. The two tools live on opposite ends of the speed/fidelity axis on purpose. Don't try to make Vitest test layout, and don't try to make Playwright your every-save runner.

Code

The default 2026 testing stack — package.json·json
{
  "devDependencies": {
    "vitest": "^4.1.5",
    "@vitest/coverage-v8": "^4.1.5",
    "@vitest/ui": "^4.1.5",
    "@testing-library/react": "^16.0.0",
    "@testing-library/user-event": "^14.5.0",
    "@testing-library/jest-dom": "^6.5.0",
    "happy-dom": "^15.0.0",
    "msw": "^2.6.0",
    "@playwright/test": "^1.48.0"
  }
}
Decision tree — three questions, four answers·text
Starting a new project?
  → Vitest + Playwright. Move on.

Have an existing Jest suite?
  → Is it large and stable? → Keep Jest. Don't migrate for fashion.
  → Is it small or already changing? → Vitest. The API is Jest-compatible.

Need component tests?
  → Vitest + React Testing Library + happy-dom. Not Playwright.

Need E2E?
  → Playwright. Skip Cypress for new projects.

Need network mocking?
  → MSW. It's the single answer for both Vitest and Playwright.

External links

Exercise

Open your terminal. List every test-related dependency in your current project's package.json — anything with 'test', 'jest', 'vitest', 'cypress', 'playwright', 'mocha', or 'chai' in the name. Classify each into the stack above (Vitest equivalent? Playwright equivalent? RTL? MSW? legacy holdover?). If there are duplicates (e.g., both Jest and Vitest), note which one is winning and why.
Hint
Common surprise: a project will have BOTH a unit runner you actively use AND a legacy E2E tool that no one runs anymore but is still in deps. That's normal — figuring out which is which is the actual decision.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.