jestjs/jest · error · Error

jest.config.mts requires native TypeScript support. Ensure…

Error message

jest.config.mts requires native TypeScript support. Ensure you are using Node.js 22.18+ or 23.6+.

What it means

Thrown when a jest.config.mts file cannot be loaded. Per the project's CLAUDE.md, .mts is always ESM and cannot be loaded via require() or ts-node. The loader first attempts native Node TypeScript support (process.features.typescript, available in Node 22.18+ / 23.6+); on any failure for .mts it throws this hard error with no fallback.

Solutions

  1. Upgrade Node.js to 22.18+ or 23.6+ where native TypeScript support is enabled
  2. If upgrade is blocked, rename the config to jest.config.ts so the ts-node/esbuild-register fallback path can be used
  3. Add an @jest-config-loader docblock pragma only if using .ts/.cts (it has no effect for .mts)
  4. Verify with node --experimental-strip-types that your Node build supports TS

Example fix

// before: jest.config.mts on Node 20
export default defineConfig({ /* ... */ });

// after option A: upgrade Node to 22.18+
// after option B: rename to jest.config.ts and add docblock
/**
 * @jest-config-loader ts-node
 */
import type {Config} from 'jest';
const config: Config = { /* ... */ };
export default config;
Defensive patterns

Strategy: validation

Validate before calling

import * as semver from 'semver';
function nodeSupportsNativeTS(): boolean {
  const major = Number(process.versions.node.split('.').map(Number)[0]);
  const minor = Number(process.versions.node.split('.')[1]);
  // 22.18+ or 23.6+
  return semver.gte(process.versions.node, '22.18.0') || semver.gte(process.versions.node, '23.6.0');
}
if (fs.existsSync('jest.config.mts') && !nodeSupportsNativeTS()) {
  throw new Error('jest.config.mts requires Node 22.18+ or 23.6+');
}

Type guard

function nodeSupportsMtsConfig(): boolean {
  // @ts-expect-error process.features.typescript is typed in newer @types/node
  return Boolean(process.features?.typescript);
}

Prevention

When it happens

Trigger: Running Jest with a jest.config.mts on an older Node version that lacks native TypeScript stripping (pre-22.18 or pre-23.6), or on a Node build with TypeScript support disabled.

Common situations: Teams adopting .mts config files without upgrading Node; CI environments pinned to older LTS Node versions; local developers on nvm with an older default.

Related errors


AI-assisted analysis of jestjs/jest@8e6d128e4a (2026-08-10). Data as JSON: /api/errors/f6ac72c35f368d52. Report an issue: GitHub.

Appendix: source

Thrown at packages/jest-config/src/readConfigFileAndSetRootDir.ts:55

    configPath.endsWith(JEST_CONFIG_EXT_TS) ||
    configPath.endsWith(JEST_CONFIG_EXT_MTS) ||
    configPath.endsWith(JEST_CONFIG_EXT_CTS);
  const isMTS = configPath.endsWith(JEST_CONFIG_EXT_MTS);
  const isJSON = configPath.endsWith(JEST_CONFIG_EXT_JSON);
  let configObject;

  try {
    if (isTS) {
      // .mts is always ESM, so attempt import-based loading first.
      // @ts-expect-error: Type assertion can be removed once @types/node is updated to 23 https://nodejs.org/api/process.html#processfeaturestypescript
      if (isMTS || process.features.typescript) {
        try {
          // Try native node TypeScript support first.
          configObject = await requireOrImportModule<any>(configPath);
        } catch (requireOrImportModuleError) {
          if (isMTS) {
            // .mts is always ESM and cannot be loaded via require()/ts-node.
            throw new Error(
              'jest.config.mts requires native TypeScript support. Ensure you are using Node.js 22.18+ or 23.6+.',
              {cause: requireOrImportModuleError},
            );
          }
          if (!(requireOrImportModuleError instanceof SyntaxError)) {
            if (!hasTsLoaderExplicitlyConfigured(configPath)) {
              throw requireOrImportModuleError;
            }
          }
          try {
            // There are various reasons of failed loadout of Jest config in Typescript:
            // 1. User has specified a TypeScript loader in the docblock and
            // desire non-native compilation (https://github.com/jestjs/jest/issues/15837)
            // 2. Likely ESM in a file interpreted as CJS, which means it needs to be
            // compiled. We ignore the error and try to load it with a loader.
            configObject = await loadTSConfigFile(configPath);
          } catch (loadTSConfigFileError) {
            // If we still encounter an error, we throw both messages combined.

View on GitHub (pinned to 8e6d128e4a)