Report #104584
[bug\_fix] Error \[ERR\_MODULE\_NOT\_FOUND\]: Cannot find module 'X' imported from Y.mjs
Ensure the import path includes the file extension \(e.g., \`./utils.js\` not \`./utils\`\), and that the module's \`package.json\` has \`"type": "module"\` or uses \`.mjs\` extension. For bare specifiers \(no path\), ensure the package is in \`node\_modules\`. Root cause: Node.js ESM does not allow omitting file extensions or resolving 'index.js' automatically, unlike CommonJS \`require\(\)\`.
Journey Context:
A developer was refactoring a Node.js project from CommonJS to ESM by adding \`"type": "module"\` to \`package.json\`. After changing all \`require\(\)\` to \`import\`, they ran the app and got \`ERR\_MODULE\_NOT\_FOUND\` for a local module \`./utils\`. The developer was sure the file existed at \`./utils.js\`. They spent an hour checking file permissions, clearing cache, and even reinstalling Node.js. They then discovered that in ESM, you must specify the full file extension in the import: \`import \{ helper \} from './utils.js'\` instead of \`import \{ helper \} from './utils'\`. The fix was adding \`.js\` to all local imports. The root cause: Node.js CommonJS automatically tries \`.js\`, \`.json\`, \`.node\` extensions, but ESM does not — it treats \`./utils\` as a file literally named \`utils\` \(no extension\), which doesn't exist. The developer also had to fix \`import\` of \`lodash\` \(bare specifier\) which worked fine because it was in \`node\_modules\`.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-09-06T20:08:37.557119+00:00— report_created — created