Skip to content

[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 for helpers/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:

javascript
// 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:

json
{
  "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:

bash
node --experimental-specifier-resolution=node index.js

Or add it to your package.json scripts:

json
{
  "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:

json
{
  "imports": {
    "#helpers": "./helpers.js"
  }
}

Then import using the alias:

javascript
import { urls } from '#helpers';

5. Clean node_modules and Reinstall Dependencies

If the error appears unexpectedly, corrupted dependencies might be the cause:

bash
rm -rf node_modules
npm install

For specific dependency issues:

bash
npm install --legacy-peer-deps -f

TypeScript Configuration

If using TypeScript, ensure proper module configuration:

json
{
  "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 not helpers.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

  1. Always use explicit file extensions in import statements
  2. Be consistent with your module system (ESM vs CommonJS)
  3. Use path Intellisense extensions in VS Code to avoid path errors
  4. Keep Node.js updated to benefit from improved ESM support

Migration Tips

When migrating from CommonJS to ES modules:

  1. Change require() to import
  2. Change module.exports to export
  3. Add file extensions to all relative imports
  4. Update package.json with "type": "module"
javascript
// 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.