Report #68567
[bug\_fix] Cannot use import statement outside a module \(SyntaxError in Node.js\) or The file is in an unsupported format \(ERR\_UNKNOWN\_FILE\_EXTENSION\)
Set \`module: "Node16"\` or \`"NodeNext"\` \(not \`"ESNext"\`\) and \`moduleResolution: "Node16"\` \(or \`"NodeNext"\`\) in \`tsconfig.json\`. Ensure \`package.json\` contains \`"type": "module"\` to enable ESM mode for \`.js\` files. When importing relative files, use explicit file extensions including \`.js\` \(e.g., \`import \{ foo \} from './bar.js'\`\), even if the source file is \`.ts\` \(TypeScript permits this "mismatch" for ESM compatibility\).
Journey Context:
A developer wants to use modern ESM syntax \(\`import/export\`\) in a Node.js project. They set \`module: "ESNext"\` in \`tsconfig.json\` and write imports like \`import express from 'express'\`. TypeScript compiles without errors, emitting \`.js\` files. However, running \`node dist/index.js\` throws "Cannot use import statement outside a module". The developer tries renaming files to \`.mjs\`, but then TypeScript emits \`.mjs\` files which confuse import resolution. They try adding \`"type": "module"\` to package.json, but then get "ERR\_UNKNOWN\_FILE\_EXTENSION" when trying to import a local file \`./utils\` without an extension. They realize that TypeScript's \`module: "ESNext"\` doesn't tell Node how to run the code. Switching to \`module: "Node16"\` forces TypeScript to emulate Node's native ESM rules, requiring explicit file extensions and correctly mapping to Node's resolution algorithm.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T21:34:38.082914+00:00— report_created — created