Fix Node.js Error: Cannot find module โ€” npm Module Not Found

beginner๐Ÿ’š Node.js2026-03-21| Node.js (all versions), npm/yarn/pnpm, Linux/macOS/Windows

Error Message

Error: Cannot find module
#nodejs#npm#module

The Error

Error: Cannot find module 'express'
Require stack:
- /home/user/myapp/app.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)

Node.js throws this when require() or import can't find what you're asking for. Three main culprits: a package was never installed, a local file path is wrong, or node_modules got corrupted somehow.

Root Causes

  • Package not installed โ€” npm install was never run, or ran in a different directory
  • Wrong relative path in require('./someFile') โ€” off by one folder level
  • Corrupted or incomplete node_modules (partial install, disk full, etc.)
  • Package listed in package.json but never actually installed locally
  • Node.js version mismatch โ€” the package requires Node 18+ but you're on 16
  • Global package referenced in a local project (or the reverse)

Fix 1: Install the Missing Package

Nine times out of ten, this is the fix. The package simply isn't there:

# npm
npm install express

# yarn
yarn add express

# pnpm
pnpm add express

Installing a dev-only tool like Jest or TypeScript? Use --save-dev so it doesn't bloat production builds:

npm install --save-dev jest

Quick sanity check:

node -e "require('express'); console.log('OK')"

Fix 2: Nuke and Reinstall node_modules

Sometimes node_modules gets out of sync with package-lock.json โ€” partial installs, switching branches, or a failed upgrade can all cause this. The clean solution:

rm -rf node_modules package-lock.json
npm install

On Windows (PowerShell):

Remove-Item -Recurse -Force node_modules
Remove-Item package-lock.json
npm install

This wipes everything and rebuilds from scratch. A fresh npm install typically takes 30โ€“90 seconds for most projects.

Fix 3: Check You're in the Right Directory

A classic trap. You run the app from a parent folder โ€” but node_modules lives in the project subfolder, not where you're standing:

# Wrong โ€” node_modules is not here
cd /home/user
node myapp/app.js

# Right
cd /home/user/myapp
node app.js

Confirm node_modules and package.json share the same directory:

ls node_modules | grep express

Fix 4: Fix a Wrong Local File Path

When the error says Cannot find module './utils', Node.js is looking for a file relative to the current module โ€” and it's not where you think it is.

// Broken: file doesn't exist at this path
const utils = require('./utils');

// Try one level up
const utils = require('../utils');

// Or inside a subfolder
const utils = require('./helpers/utils');

Not sure which directory Node.js thinks you're in? Print it:

console.log(__dirname);  // absolute path of the current file

Fix 5: TypeScript / ESM Path Issues

TypeScript with "moduleResolution": "NodeNext" has a quirk: you import .js extensions even though the source files are .ts. It looks wrong but it's correct โ€” the compiler resolves it at build time.

// This imports foo.ts โ€” the .js extension is intentional
import { foo } from './foo.js';

Running ts-node and hitting module errors? Try the ESM flag:

npx ts-node --esm app.ts

Or switch to the more forgiving resolver in tsconfig.json:

{
  "compilerOptions": {
    "moduleResolution": "node"
  }
}

Fix 6: Global vs Local Package Conflict

Tools like nodemon or ts-node are often installed globally, but package.json scripts expect a local copy. Install them as dev dependencies to keep things consistent across machines:

npm install --save-dev nodemon ts-node

To see where a package lives:

npm list express        # local install
npm list -g express     # global install

Fix 7: NODE_PATH for Monorepos

Custom setups and monorepos sometimes need explicit module resolution hints. If Node.js can't find a shared package across workspace folders:

# One-off run
NODE_PATH=./src node app.js

# Bake it into package.json scripts
"scripts": {
  "start": "NODE_PATH=./src node app.js"
}

Verification Steps

  • Confirm the package is listed: cat package.json | grep express
  • Confirm it's physically installed: ls node_modules/express
  • Test the require directly: node -e "require('express'); console.log('loaded')"
  • Run your app: node app.js โ€” the error should be gone

Prevention

  • Commit package.json and package-lock.json โ€” never commit node_modules
  • After cloning a repo or pulling changes with new deps, run npm install immediately
  • Add node_modules/ to .gitignore โ€” without this, repos balloon by hundreds of MB
  • Use npm ci in CI/CD pipelines; unlike npm install, it respects the lockfile exactly
  • Pin a minimum Node.js version in package.json to catch engine mismatches early: "engines": { "node": ">=18" }

Related Error Notes