Skip to content
Latchkey

Vitest/Jest "import.meta" Undefined - env & glob Not Available in Tests

import.meta is an ESM-only construct. Under Jest’s default CommonJS runtime it is a syntax error, and even under Vitest, import.meta.env values depend on the resolved mode - so tests can see undefined where the app sees a value.

What this error means

A module using import.meta.env.VITE_X or import.meta.glob fails in tests: Jest throws "Cannot use import.meta outside a module," or Vitest reads import.meta.env.VITE_X as undefined even though the dev build has it.

Test output
SyntaxError: Cannot use 'import.meta' outside a module

  > 3 | const base = import.meta.env.VITE_API_URL;
      |                     ^
  (Jest, default CommonJS runtime)

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

Jest CommonJS has no import.meta

Jest transpiles to CommonJS by default, where import.meta does not exist. Code that reads import.meta.env breaks at parse/eval time unless mapped or polyfilled.

Vitest env not loaded for tests

Vitest exposes import.meta.env, but only variables present in the resolved mode/.env are defined. A VITE_-prefixed var missing from the test environment reads as undefined.

How to fix it

In Vitest, provide env values for tests

Define the values Vitest should expose, or set them in a setup file.

vitest.config.ts
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
  define: { 'import.meta.env.VITE_API_URL': JSON.stringify('http://localhost') },
  test: { env: { VITE_API_URL: 'http://localhost' } },
});

In Jest, avoid raw import.meta

  1. Read config through a small wrapper (getApiUrl()) you can mock in Jest, instead of import.meta inline.
  2. Or run Jest in native ESM (NODE_OPTIONS=--experimental-vm-modules) with a transform that preserves import.meta.
  3. Provide a Babel plugin to rewrite import.meta.env to process.env for the Jest build.

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

  • Centralize env access behind a wrapper so tests can mock it.
  • Define required import.meta.env values in the Vitest config.
  • Prefer Vitest for Vite apps that lean on import.meta.

Frequently asked questions

What causes Vitest/Jest "import.meta" undefined?
There are 2 common causes: jest commonjs has no import.meta and vitest env not loaded for tests. Jest transpiles to CommonJS by default, where import.meta does not exist.
How do I fix Vitest/Jest "import.meta" undefined?
There are 2 fixes depending on which cause you have: in vitest, provide env values for tests and in jest, avoid raw import.meta. Work through them in order, since the first is the most common.
What does Vitest/Jest "import.meta" undefined actually mean?
A module using import.meta.env.VITE_X or import.meta.glob fails in tests: Jest throws "Cannot use import.meta outside a module," or Vitest reads import.meta.env.VITE_X as undefined even though the dev build has it.
How do I stop Vitest/Jest "import.meta" undefined happening again?
Centralize env access behind a wrapper so tests can mock it. 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