Jest · Unit tests that survive refactors

How do you run native ES modules with Jest?

HardesmmodulesconfigurationUpdated Oct 2026
Quiz this track

Short answer

Native ESM needs --experimental-vm-modules or a transform to CommonJS. Align package.json type, tsconfig module and Jest settings, because mixing module systems causes require and import errors.

Jest historically ran CommonJS. Native ESM support exists but still has different behaviour for mocking and the module registry. The practical choice is either to compile tests to CommonJS or to opt into ESM consistently across the toolchain.

bash
NODE_OPTIONS=--experimental-vm-modules npx jest
ESM mode requires the VM modules flag and a package.json with type set to module. Without the flag, Jest reports an unexpected token on import.

Symptoms of a mismatch

  • Cannot use import statement outside a module
  • require is not defined in ES module scope
  • A module mock does not apply because the import was not transformed the same way
  • A dependency ships ESM and Jest tries to require it as CommonJS
  • import.meta is unavailable in the CommonJS transform

With ts-jest, ESM mode needs a tsconfig with an ESM module target and the ESM preset, plus the VM modules flag. With Babel, the transform must preserve ESM rather than converting it. In both cases, test utilities that mutate exports, such as some spies, behave differently because ESM bindings are read-only.

Do not mix module systems just to make one dependency work. Pick one target for the test run, then handle the outlier package with a transform allowlist or a small compatibility wrapper. Mixed modes create failures that are hard to reproduce outside the test runner.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1What does the experimental VM modules flag change?
  2. 2Why does jest.spyOn fail on some ESM exports?
  3. 3How do you handle an ESM-only dependency in a CommonJS test run?
  4. 4What is import.meta and why does it break in CommonJS?

Say it in the interview

Jest can run native ESM, but it needs the VM modules flag and consistent configuration. More often I compile tests to CommonJS, because that is the stable path and avoids mocking differences. When I do use ESM, I align package type, tsconfig module and the transform. ESM bindings are read-only, so some spies and module mutations that worked in CommonJS no longer work.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Jest mock interview and get scored feedback on depth, clarity and confidence.