Report #13465
[bug\_fix] Cannot use import statement outside a module when running compiled TypeScript in Node.js, or TS2691: An import path cannot end with a '.ts' extension
Set \`module: "NodeNext"\` and \`moduleResolution: "NodeNext"\` in \`tsconfig.json\`, and use explicit \`.ts\` extensions in import specifiers \(e.g., \`import \{ foo \} from './foo.ts'\`\). TypeScript will emit \`.js\` extensions in the output but requires the \`.ts\` in source to support Node.js ESM resolution.
Journey Context:
Developer decides to use native Node.js ESM \(\`"type": "module"\` in package.json\) for a new TypeScript project. They write \`import \{ helper \} from './helper';\` in \`index.ts\`. TypeScript complains it cannot find the module or asks for a relative path with extension. They change it to \`import \{ helper \} from './helper.ts';\`. TypeScript now errors \`TS2691: An import path cannot end with a '.ts' extension\`. Frustrated, they search and find that TypeScript historically didn't support the \`.ts\` extension in imports because it emitted \`.js\`. They find the GitHub issue announcing support in TS 4.7 via \`moduleResolution: node16/nodenext\`. They update \`tsconfig.json\` to \`module: "NodeNext"\` and \`moduleResolution: "NodeNext"\`. Now they can write \`./helper.ts\` in the source, and the compiler accepts it, emitting \`./helper.js\` in the \`dist\` folder. Node.js ESM resolves the file correctly at runtime. The developer understands that \`NodeNext\` mode aligns TS resolution with Node's native ESM algorithm.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T18:48:40.373082+00:00— report_created — created