{"id":"f6ac72c35f368d52","repo":"jestjs/jest","slug":"jest-config-mts-requires-native-typescript-support","errorCode":null,"errorMessage":"jest.config.mts requires native TypeScript support. Ensure you are using Node.js 22.18+ or 23.6+.","messagePattern":"jest\\.config\\.mts requires native TypeScript support\\. Ensure you are using Node\\.js 22\\.18\\+ or 23\\.6\\+\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/jest-config/src/readConfigFileAndSetRootDir.ts","lineNumber":55,"sourceCode":"    configPath.endsWith(JEST_CONFIG_EXT_TS) ||\n    configPath.endsWith(JEST_CONFIG_EXT_MTS) ||\n    configPath.endsWith(JEST_CONFIG_EXT_CTS);\n  const isMTS = configPath.endsWith(JEST_CONFIG_EXT_MTS);\n  const isJSON = configPath.endsWith(JEST_CONFIG_EXT_JSON);\n  let configObject;\n\n  try {\n    if (isTS) {\n      // .mts is always ESM, so attempt import-based loading first.\n      // @ts-expect-error: Type assertion can be removed once @types/node is updated to 23 https://nodejs.org/api/process.html#processfeaturestypescript\n      if (isMTS || process.features.typescript) {\n        try {\n          // Try native node TypeScript support first.\n          configObject = await requireOrImportModule<any>(configPath);\n        } catch (requireOrImportModuleError) {\n          if (isMTS) {\n            // .mts is always ESM and cannot be loaded via require()/ts-node.\n            throw new Error(\n              'jest.config.mts requires native TypeScript support. Ensure you are using Node.js 22.18+ or 23.6+.',\n              {cause: requireOrImportModuleError},\n            );\n          }\n          if (!(requireOrImportModuleError instanceof SyntaxError)) {\n            if (!hasTsLoaderExplicitlyConfigured(configPath)) {\n              throw requireOrImportModuleError;\n            }\n          }\n          try {\n            // There are various reasons of failed loadout of Jest config in Typescript:\n            // 1. User has specified a TypeScript loader in the docblock and\n            // desire non-native compilation (https://github.com/jestjs/jest/issues/15837)\n            // 2. Likely ESM in a file interpreted as CJS, which means it needs to be\n            // compiled. We ignore the error and try to load it with a loader.\n            configObject = await loadTSConfigFile(configPath);\n          } catch (loadTSConfigFileError) {\n            // If we still encounter an error, we throw both messages combined.","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/jestjs/jest/blob/f49721c78e195558b40913977c9230f5b7f559d8/packages/jest-config/src/readConfigFileAndSetRootDir.ts#L37-L73","documentation":"Jest config files ending in .mts are always ESM and cannot be loaded via require() or ts-node. Jest first attempts native Node TypeScript support (process.features.typescript, available on Node 22.18+ / 23.6+). If that import fails for a .mts file there is no fallback loader, so this hard error is thrown pointing at the Node version requirement.","triggerScenarios":"Using a jest.config.mts file on Node < 22.18 (or < 23.6 on the 23 line), or on a Node build compiled without the experimental TypeScript flag enabled.","commonSituations":"Upgrading a project to ESM and renaming jest.config.ts to jest.config.mts while the CI Node version lags; local dev using an older Node via nvm; corporate Node LTS pinning.","solutions":["Upgrade Node to 22.18+ or 23.6+ (or any later release that ships native TypeScript)","Rename the config to jest.config.ts or jest.config.cts so the ts-node/esbuild-register fallback path applies","Run Node with --experimental-strip-types if on a version that supports it but does not enable it by default"],"exampleFix":"// before: jest.config.mts on Node 20\nexport default {testEnvironment: 'node'};\n// after option A: upgrade Node to 22.18+\n// after option B: rename to jest.config.cts\nmodule.exports = {testEnvironment: 'node'};","handlingStrategy":"validation","validationCode":"import * as semver from 'semver';\nfunction nodeSupportsNativeTS(): boolean {\n  return Boolean((process as any).features?.typescript) ||\n    semver.gte(process.version, '22.18.0') ||\n    semver.gte(process.version, '23.6.0');\n}\nif (configPath.endsWith('.mts') && !nodeSupportsNativeTS()) {\n  throw new Error('Upgrade Node to 22.18+ for jest.config.mts');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin CI Node version >= 22.18 when using .mts configs","Prefer .ts/.cts config if you must support older Node","Document the Node version requirement next to any .mts rename"],"tags":["typescript","esm","node","config"],"analyzedSha":"f49721c78e195558b40913977c9230f5b7f559d8","analyzedAt":"2026-08-03T20:16:28.571Z","schemaVersion":2}