Fix ERR_MODULE_NOT_FOUND for local modules in Node.js
Node.js can't find local module 'X' after updating dependencies. Usually a cache or path issue. Here's the fix.
Quick answer
Delete node_modules and package-lock.json, run npm install fresh, and double-check your import path uses ./ prefix for local files (not bare module names).
Why this happens
This error usually pops up right after you update package.json dependencies. Maybe you ran npm update or manually changed a version. The module system—especially ECMAScript modules (ESM) in Node.js 16 and later—loses track of local modules. It treats them like they're in node_modules when they're not. I've seen this on Node 18.17 and 20.11, mostly with ESM projects using "type": "module" in package.json. The common trigger: you update a dependency that also exports some local utility module, and the import path breaks.
The real culprit is often a stale node_modules cache or a missing ./ in the import statement. Node's ESM resolution is strict: bare specifiers like import 'myModule' look in node_modules, not your project root. If you meant a local file, you need import './myModule.js'.
Fix steps
- Clean up completely. Delete
node_modulesandpackage-lock.json(oryarn.lock). Don't skip this. A partial clean leaves stale symlinks.rm -rf node_modules package-lock.json - Reinstall dependencies.
Or if you use Yarn:npm installyarn install. This rebuilds everything from scratch. - Check your import path. Open the file that triggers the error. Look at the import statement. For a local module named
helperin the same folder, it must be:import './helper.js'orimport './helper/index.js'. If you wroteimport 'helper', Node will searchnode_modulesand fail with ERR_MODULE_NOT_FOUND. - Verify module exports. In the local module file, make sure it actually exports something. For ESM, use
export defaultor named exports. A missing export can cause the error, even if the file exists.// helper.js export default function helper() { return 'hello'; } - Restart the process. Kill your Node process (Ctrl+C) and restart it. In some cases, Node holds a cached module resolution and doesn't pick up changes until restart.
Alternative fixes if the main one fails
- Use npm cache clean. If the fresh install doesn't work, the npm cache might be corrupted. Run
npm cache clean --forcethen reinstall. This clears all cached packages that could conflict with resolution. - Check for duplicate module names. If your local module has the same name as a package in
node_modules, Node will prefer the external one. Rename your local module or use a deeper path likeimport './src/helper.js'. - Use
--experimental-specifier-resolution=node(Node 18 and earlier). Some older projects rely on Node.js CommonJS-style resolution without./. This flag lets you omit./for local files, but it's deprecated in Node 20. I don't recommend it—better to fix the path. - Switch to CommonJS temporarily. If you're stuck, rename your file to
.cjsand userequire('./helper'). This bypasses ESM resolution entirely. It's a band-aid, not a solution.
Prevention tip
Set a consistent import convention from day one. Always prefix local imports with ./ or ../. Never use bare module names for your own code. This habit saves you from ERR_MODULE_NOT_FOUND every time dependencies change. Also, pin your Node version in .nvmrc or engines in package.json—different Node releases handle module resolution slightly differently.
One more thing: if you're using a monorepo with workspaces, make sure your local modules are properly referenced in workspaces or package.json exports field. That's a whole other beast, but it starts with the same principle: explicit paths.
I've been burned by this error more times than I care to count. The clean install plus path check solves 90% of cases. The rest is just debugging the edge cases.
Was this solution helpful?