Report #40781
[bug\_fix] TS2792: Cannot find module './utils.js'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
Set \`"moduleResolution": "node"\` \(or \`"bundler"\` in TS 4.7\+ for ESM\) in tsconfig.json compilerOptions. For ESM, ensure import specifiers use \`.js\` extensions even for \`.ts\` files. Root cause: TypeScript defaults to \`classic\` resolution in some configurations, and ESM requires explicit file extensions which TypeScript does not rewrite.
Journey Context:
You're migrating a project to ES Modules \(ESM\) with \`"type": "module"\` in package.json and \`"module": "ESNext"\` in tsconfig. You rename files to \`.ts\` and try to import \`./utils\`. TypeScript complains it cannot find the module, or at runtime Node says 'Cannot find module...'. You check that the file exists at \`src/utils.ts\`. You try adding \`.ts\` extension in the import, but TypeScript says 'An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.' You enable that, but then \`tsc\` compilation fails because it can't emit JS files with TS extensions. You're stuck. You read the TypeScript 4.7 release notes about ESM support. You realize that for ESM output, you must write import specifiers with \`.js\` extensions \(e.g., \`./utils.js\`\) even though the source file is \`.ts\`. TypeScript's module resolution strategy needs to be \`node\` \(or \`bundler\` for more flexibility\) to handle this. Changing \`moduleResolution\` to \`node\` allows TypeScript to resolve \`./utils.js\` to \`./utils.ts\` during type-checking, while the emitted JS retains the \`.js\` extension required by ESM Node.js runtime.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T22:55:17.051658+00:00— report_created — created