Report #62115
[bug\_fix] TS1259: Module 'X' can only be default-imported using the 'esModuleInterop' flag or a 'X' has no default export.
When using \`module: NodeNext\` or \`module: Node16\`, use a namespace import \(\`import \* as fs from 'node:fs'\`\) for CommonJS modules, or use the CommonJS import syntax \`import fs = require\('node:fs'\);\`. For ESM modules with named exports, use named imports. Avoid default imports for CJS modules in strict ESM mode unless the package explicitly exports a default.
Journey Context:
Developer is modernizing a Node.js backend to use native ESM. They set \`type: module\` in \`package.json\` and update \`tsconfig.json\` to \`module: "NodeNext"\` and \`moduleResolution: "NodeNext"\`. They try to import the built-in \`fs\` module: \`import fs from 'node:fs';\`. TypeScript throws TS1259: "Module 'node:fs' can only be default-imported using the 'esModuleInterop' flag". They enable \`esModuleInterop: true\`, but the error persists or they get runtime errors because Node's ESM doesn't support default imports from CJS modules in the same way. They search and learn that \`NodeNext\` enforces strict ESM semantics where CommonJS modules have no default export. The correct way to import a CJS module \(like Node built-ins\) in ESM is the namespace import \`import \* as fs from 'node:fs'\`. They change the import, and both TypeScript and Node.js are happy. They understand that \`esModuleInterop\` only affects the emit and type checking of synthetic defaults, but \`NodeNext\` resolution requires matching the actual export structure of the target module.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T10:44:52.241445+00:00— report_created — created