Jest TypeScript ESM support


This post goes over how to enable ECMAScript Modules (ESM) support for Jest tests written in TypeScript.

Prerequisites

Your Jest is configured with ts-jest:

// jest.config.ts
import type { Config } from 'jest';

const config: Config = {
  preset: 'ts-jest',
};

export default config;

Scripts

Update your package.json script “test”:

 {
   "scripts": {
-    "test": "jest"
+    "test": "node --experimental-vm-modules $(npx which jest)"
   }
 }

npx which jest evaluates to node_modules/.bin/jest.

Or alternatively:

 {
   "scripts": {
-    "test": "jest"
+    "test": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" jest
   }
 }

Configs

Update your Jest config to transform using ESM:

 // jest.config.ts
 import type { Config } from 'jest';

 const config: Config = {
-  preset: 'ts-jest',
+  extensionsToTreatAsEsm: ['.mts', '.ts'],
+  moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1' },
+  transform: { '^.+\\.m?[tj]sx?$': ['ts-jest', { useESM: true }] },
 };

 export default config;

Set module to esnext (or es2022) in your tsconfig.json:

 {
   "compilerOptions": {
     "target": "es2022",
+    "module": "esnext",
     "moduleResolution": "node"
   }
 }

Tests

Import jest to access the object:

import { jest } from '@jest/globals';
jest.fn();

Use await import to import relative files:

const { myUtil } = await import('./my-util.js');

ESM relative import must include the file extension.

Mock a module with jest.unstable_mockModule:

jest.unstable_mockModule('node:os', () => ({
  platform: jest.fn(),
}));

Both the 1st and 2nd arguments are required.

Unmock with jest.unstable_unmockModule:

jest.unstable_unmockModule('node:os');


Please support this site and join our Discord!