Report #60989
[bug\_fix] Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './utils.js'? \(TS2834/2835\)
Add the \`.js\` extension to relative imports in TypeScript source files \(e.g., \`import \{ foo \} from './utils.js'\`\), even when importing \`.ts\` files. Alternatively, if targeting CommonJS, ensure \`module\` is set to \`CommonJS\` and \`moduleResolution\` to \`Node\`. The root cause is that ES Modules require explicit file extensions in import specifiers, and TypeScript 4.7\+ enforces this compatibility when using \`Node16\` or \`NodeNext\` module resolution.
Journey Context:
You upgraded to TypeScript 4.7\+ to support native ES Modules in Node.js, setting \`module: "NodeNext"\`, \`moduleResolution: "NodeNext"\`, and \`target: "ES2022"\` in \`tsconfig.json\`, with \`"type": "module"\` in \`package.json\`. You have \`src/utils.ts\` and \`src/index.ts\`. In \`index.ts\`, you write \`import \{ helper \} from './utils'\`. TypeScript immediately errors: "Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean './utils.js'?". You're confused because the file is \`.ts\`, not \`.js\`. You try changing it to \`./utils.ts\`, but TypeScript says "Cannot find module './utils.ts' or its corresponding type declarations. Consider using '--extension' flag or changing the file extension to '.js'." Searching the TypeScript 4.7 release notes, you learn that for ES Module compliance, import specifiers must include the file extension as it will appear at runtime \(\`.js\`\), and TypeScript's module resolution will map \`./utils.js\` to \`./utils.ts\` during compilation. You change the import to \`./utils.js\` and the error resolves, with TypeScript correctly resolving to the \`.ts\` source file during type-checking and emitting the \`.js\` extension in the compiled output.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T08:51:32.515186+00:00— report_created — created