Report #91740
[bug\_fix] TS2835: Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'.
Use explicit \`.js\` file extensions in import specifiers for relative paths \(e.g., \`import \{ foo \} from './utils.js'\`\), even when importing TypeScript files. Ensure package.json contains \`"type": "module"\` for ESM.
Journey Context:
Developer upgrades TypeScript to 5.x or switches \`moduleResolution\` to \`NodeNext\` to properly support ES Modules in Node.js. Suddenly, every relative import like \`import \{ helper \} from './utils'\` throws \`TS2835\`. The error message suggests adding extensions. Developer tries \`import from './utils.ts'\` but gets \`TS2691: An import path cannot end with a '.ts' extension\`. Confused, they search and find that TypeScript follows the Node.js ESM specification, which requires explicit file extensions, and since TypeScript emits \`.js\` files, the source must reference the output extension. The developer reluctantly changes all imports to use \`.js\` extensions \(\`import from './utils.js'\`\), which feels wrong in a TS file but compiles correctly. The fix is confirmed when \`tsc\` runs without errors and the generated \`.js\` files contain working relative paths with \`.js\` extensions.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T12:34:39.914517+00:00— report_created — created