Vitest 5: clearMocks on by default, Node 22.12+, Vite 6.4+, stricter hoisting and async assertions
Vitest 5: clearMocks on by default, Node 22.12+, Vite 6.4+, stricter hoisting and async assertions
Vitest 5.0.0 shipped 2026-09-03 (current 5.0.3). It needs Node ^22.12 and Vite >= 6.4. Mocks are cleared before each test by default, test.sequential was removed, unawaited async assertions fail, vi.mock must be top-level, and deprecated entry points were removed.
Vitest 5 migration (and what Vitest 4 already changed)
As of: 2026-10
Versions
vitest@5.0.0was released 2026-09-03. The currentlatestis5.0.3(2026-09-30).- Previous lines are still published:
4.1.11(npm tagV4) and3.2.7(V3).4.0.0was released 2025-10-22. - Requirements: Node
^22.12.0 || ^24.0.0 || >=26.0.0. Thevitepeer is^6.4.0 || ^7.0.0 || ^8.0.0; Yarn users must installviteexplicitly.
Vitest 5 breaking changes
1. clearMocks defaults to true. Call history resets before each test, but implementations are kept. Counters that used to accumulate across tests now start at zero. Set clearMocks: false to opt out.
2. -t uses > between suite and test names: vitest -t 'math > adds'.
3. Hoisted calls must be top-level. vi.mock, vi.unmock and vi.hoisted inside describe or a function now throw an error.
4. Unawaited async assertions fail the test instead of only warning:
await expect(p).resolves.toBe(1); // required
5. test.sequential and describe.sequential were removed:
describe('suite', { concurrent: false }, () => { /* ... */ });
6. Benchmark API rewritten. bench is now a test-context fixture:
test('sort', async ({ bench }) => { await bench('sort', () => [3,1,2].sort()).run(); });
7. Config and projects.
- The config file is no longer searched for in parent directories, so pass
--configwhen needed. - Inline
test.projectsnow inherit the root config, including plugins and aliases, unless they setextends: false. Nested projects are supported.
8. Removed entry points.
vitest/coverageandvitest/reportersmove tovitest/node.vitest/environmentsandvitest/snapshotmove tovitest/runtime.@vitest/runneris no longer published separately, andexpectis inlined.
9. Other changes.
VITEST_POOL_ID/VITEST_WORKER_IDare now 1-based.- Default output paths moved to
.vitest/: blob, json, junit and html reports, plusattachmentsDir(.vitest/attachments/). - Values are formatted with pretty-format instead of loupe, so snapshots and messages differ.
expect.pollfails if the function doesn't resolve in time.- Class mocks keep their prototype methods and pass
instanceof. - Fake timers can mock
Temporal. - The UI (
/__vitest__/) requires a printed token. - Browser mode: locators are exact by default (
browser.locators.exact: falseto revert),toHaveTextContentis strict (toMatchTextContentis the loose variant), and the webdriverio package was removed.
Already changed in Vitest 4 (often still wrong in generated code)
- The
workspaceoption andvitest.workspacefile were removed; usetest.projects. environmentMatchGlobs/poolMatchGlobsand thebasicreporter were removed.- Vite 5 is no longer supported.
vite-nodewas replaced by Vite's module runner, and pools were rewritten withouttinypool.minWorkerswas removed. - Browser mode takes a provider factory, not a string.
- Obsolete snapshots fail the run on CI.
What to do now
- Upgrade Node to 22.12+ and Vite to 6.4+ first.
- Search the code for
.sequential, nestedvi.mock, unawaited.resolves/.rejects, old entry-point imports, and tests that count mock calls across tests.