Vitest "Cannot find package happy-dom / jsdom" - DOM Environment
Vitest can run DOM tests under happy-dom or jsdom, but neither ships with Vitest. If environment is set to one that is not installed, Vitest cannot load it and fails before any test runs.
What this error means
A component suite fails at startup with "Cannot find package 'happy-dom'" (or jsdom). The same config works on a teammate’s machine where the DOM package happens to be installed.
Error: Cannot find package 'happy-dom' imported from
/app/node_modules/vitest/dist/environments.js
Did you forget to install it? `npm i -D happy-dom`Diagnose it: flake, environment, or genuine failure?
Before debugging the assertion, establish whether the test is deterministic. A test that fails only in CI is usually order-dependent, time-dependent, or racing something, and fixing the assertion will not help.
# does it fail in isolation?
npx vitest run path/to/file.test.ts
# is it order dependent? run the suite in a random order twice
npx vitest run --sequence.shuffle
# is it a race? run the same file repeatedly
for i in $(seq 1 20); do npx vitest run path/to/file.test.ts || break; doneCommon causes
DOM environment package not installed
Vitest treats happy-dom/jsdom as optional peers. Setting environment: "happy-dom" without installing it leaves Vitest unable to resolve the environment.
API gaps between happy-dom and jsdom
happy-dom is faster but implements a narrower DOM surface. Code relying on a jsdom-only API can fail under happy-dom even once installed - the two are not drop-in equivalents.
How to fix it
Install the chosen DOM environment
npm install -D happy-dom # faster, lighter
# or
npm install -D jsdom # broader DOM coverageSet the environment explicitly
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: { environment: 'happy-dom' }, // or 'jsdom'
});
// or per file:
// @vitest-environment jsdomCI-only causes worth ruling out
- Runners have fewer cores than a laptop, so timing-sensitive tests that pass locally fail under contention.
- No TTY and a different locale or timezone. Snapshot tests containing formatted dates or numbers are the usual casualty; pin
TZandLANGin the job. - Parallel workers sharing a database, a port, or a temp directory. Give each worker its own namespace.
- Default timeouts calibrated on a fast machine. A cold runner is slower on first execution, especially before any cache warms.
How to prevent it
- Add the DOM environment package to devDependencies.
- Pick happy-dom for speed, jsdom for broader API coverage - and document the choice.
- Use the per-file
@vitest-environmentdocblock for the few tests that need the other one.