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
- Upgrade Node.js to 22.18+ or 23.6+ where native TypeScript support is enabled
- If upgrade is blocked, rename the config to jest.config.ts so the ts-node/esbuild-register fallback path can be used
- Add an @jest-config-loader docblock pragma only if using .ts/.cts (it has no effect for .mts)
- 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
- Pin your project's engines.node to >=22.18 in package.json
- Add a CI step that fails if Node version is below the threshold when a .mts config exists
- Use a .nvmrc or .node-version file committed to the repo
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
- Jest: Failed to parse the TypeScript config file
- Jest: ' ' is not a valid TypeScript configuration loader.
- Jest: ' ' is required for the TypeScript configuration…
- Jest: You can only define a single loader through…
- Can't find a root directory while resolving a config file…
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)