[ERR_MODULE_NOT_FOUND]: Cannot find module
Encountering the Error [ERR_MODULE_NOT_FOUND]: Cannot find module
error in Node.js can be frustrating, especially when the file clearly exists. This common error typically occurs when using ES modules (ESM) instead of CommonJS, and understanding the differences between these module systems is key to resolving it.
Problem Overview
When using ES modules in Node.js (with "type": "module"
in package.json), the import behavior changes significantly from CommonJS:
- File extensions are mandatory for relative imports
- Directory index file resolution (e.g.,
./helpers
looking forhelpers/index.js
) requires special configuration - Module resolution follows stricter ECMAScript specifications
The error message usually suggests the solution:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/path/to/module' imported from /path/to/file.js
Did you mean to import ../module.js?
Solutions
1. Add File Extension to Import Statements
The most straightforward fix is to explicitly include the .js
extension in your import statements:
// Before (causes error)
import { urls } from './helpers';
// After (works correctly)
import { urls } from './helpers.js';
Why Extensions Matter
ES modules require explicit file extensions to maintain browser compatibility and avoid ambiguity. Unlike CommonJS, Node.js won't automatically try different extensions (.js, .json, .node).
2. Configure package.json for ES Modules
Ensure your package.json specifies the module type:
{
"name": "your-project",
"type": "module",
// other configurations...
}
3. Use Experimental Resolution Flag (Node.js < 12.17.0)
For older Node.js versions, you can enable experimental resolution behavior that mimics CommonJS:
node --experimental-specifier-resolution=node index.js
Or add it to your package.json scripts:
{
"scripts": {
"start": "NODE_OPTIONS='--experimental-specifier-resolution=node' node index.js"
}
}
Experimental Flag
The --experimental-specifier-resolution
flag is experimental and may change in future Node.js versions. It's better to use explicit file extensions for production code.
4. Alternative: Subpath Imports (Node.js 14.13.0+)
Use package.json imports field to create import aliases:
{
"imports": {
"#helpers": "./helpers.js"
}
}
Then import using the alias:
import { urls } from '#helpers';
5. Clean node_modules and Reinstall Dependencies
If the error appears unexpectedly, corrupted dependencies might be the cause:
rm -rf node_modules
npm install
For specific dependency issues:
npm install --legacy-peer-deps -f
TypeScript Configuration
If using TypeScript, ensure proper module configuration:
{
"compilerOptions": {
"lib": ["es2020"],
"module": "ES2022",
"moduleResolution": "node",
"target": "es2022"
}
}
Common Pitfalls and Solutions
Common Mistakes Checklist
- ✅ Missing file extension: Always include
.js
in imports - ✅ Incorrect relative path: Use
./helpers.js
nothelpers.js
- ✅ Missing package.json type: Add
"type": "module"
to package.json - ✅ Case sensitivity: File paths are case-sensitive on some systems
- ✅ File existence: Verify the file actually exists at the specified path
Best Practices
- Always use explicit file extensions in import statements
- Be consistent with your module system (ESM vs CommonJS)
- Use path Intellisense extensions in VS Code to avoid path errors
- Keep Node.js updated to benefit from improved ESM support
Migration Tips
When migrating from CommonJS to ES modules:
- Change
require()
toimport
- Change
module.exports
toexport
- Add file extensions to all relative imports
- Update package.json with
"type": "module"
// helpers.js - ES Module export
export function urls(param1, param2) {
// your implementation
}
// Instead of CommonJS: module.exports = { urls: urls }
By following these guidelines, you can avoid the ERR_MODULE_NOT_FOUND
error and ensure your Node.js applications work correctly with ES modules.