Skip to content
Latchkey

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.

Vitest output
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.

Terminal
# 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; done

Common 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

Terminal
npm install -D happy-dom   # faster, lighter
# or
npm install -D jsdom        # broader DOM coverage

Set the environment explicitly

vitest.config.ts
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
  test: { environment: 'happy-dom' }, // or 'jsdom'
});
// or per file:
// @vitest-environment jsdom

CI-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 TZ and LANG in 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-environment docblock for the few tests that need the other one.

Frequently asked questions

What causes Vitest "Cannot find package happy-dom / jsdom"?
There are 2 common causes: dom environment package not installed and api gaps between happy-dom and jsdom. Vitest treats happy-dom/jsdom as optional peers.
How do I fix Vitest "Cannot find package happy-dom / jsdom"?
There are 2 fixes depending on which cause you have: install the chosen dom environment and set the environment explicitly. Work through them in order, since the first is the most common.
What does Vitest "Cannot find package happy-dom / jsdom" actually mean?
A component suite fails at startup with "Cannot find package 'happy-dom'" (or jsdom).
How do I stop Vitest "Cannot find package happy-dom / jsdom" happening again?
Add the DOM environment package to devDependencies. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

Not every red build is your code. Latchkey repairs the ones that are not, on the runner. Start free → 30-day trial · No credit card