What you'll learn
Quick Answer
Most npm failures fall into four groups. ERESOLVE means two packages demand conflicting versions of a dependency. EACCES means a permissions problem, almost always caused by having used sudo previously. ENOENT usually means npm cannot find package.json because you are in the wrong folder. And cannot find module means the package is not installed or node_modules is stale. Read the error code first — it identifies the category faster than the surrounding text.
Read the Error Code, Not the Wall of Text
npm output is verbose, but the useful part is a short code near the start.
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency treeThat code — ERESOLVE, EACCES, ENOENT, ELIFECYCLE, ETARGET — tells you the category. Everything after it is detail.
npm also writes a full log, and the path is printed at the end of the output:
npm ERR! A complete log of this run can be found in:
npm ERR! /home/user/.npm/_logs/2026-08-06T...-debug.logThat log is worth opening when the terminal output has scrolled or been truncated. It contains the resolution steps npm attempted, which usually shows exactly which two packages disagreed.
Before anything else, check your versions — a surprising number of problems are simply an old npm or a Node version a package does not support:
node -v
npm -v
ERESOLVE: Conflicting Dependencies
The most common modern npm error, and the most misunderstood.
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! Found: react@18.2.0
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^17.0.0" from some-library@3.1.0Read it plainly: you have React 18, and some-library declares it works with React 17. npm 7 and later refuse to install conflicting peer dependencies rather than silently proceeding as npm 6 did.
Three responses, in order of preference.
Check whether a newer version of the library supports your version. This is the real fix and often exists already:
npm view some-library versions --json
npm install some-library@latestUse --legacy-peer-deps to install anyway, replicating npm 6 behaviour. Usually fine, because many peer ranges are simply out of date — but you are asserting compatibility yourself.
npm install --legacy-peer-depsAvoid --force unless nothing else works. It can install a genuinely broken tree that fails later at runtime, which is far harder to diagnose than an install error.
EACCES: Permission Denied
npm ERR! code EACCES
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'npm is trying to write somewhere your user does not own. On macOS and Linux this usually means a global install into a system directory.
The instinct is sudo npm install. Resist it. Installing as root creates root-owned files in your project and cache, and then ordinary commands fail with permission errors afterwards — which people fix with more sudo, compounding the problem.
If you have already done this, repair ownership of the cache:
sudo chown -R $(whoami) ~/.npmThe durable fix is to stop needing global installs at all. Use npx to run a tool once without installing it:
npx create-react-app my-appAnd manage Node itself with a version manager such as nvm, which installs into your home directory where no elevated permissions are required. That also lets you switch Node versions per project, which solves a separate class of problem.
On Windows the same code usually means a file is locked by a running process — close your editor or dev server and retry.
ENOENT and Cannot Find Module
ENOENT means a file or directory does not exist. The most frequent version:
npm ERR! code ENOENT
npm ERR! enoent ENOENT: no such file or directory, open '/home/user/package.json'You are running npm in a folder with no package.json — usually one level above or below the project. Check with ls or dir, then cd into the right place. If the project genuinely has none, create one with npm init -y.
Cannot find module is the runtime counterpart:
Error: Cannot find module 'express'Either it was never installed, or it was installed as a dev dependency and you are running in production, or node_modules is stale after switching branches.
npm install express # runtime dependency
npm install --save-dev jest # tooling onlyNote that npm install --production and NODE_ENV=production skip devDependencies, which is why a deployment can fail on a package that works locally.
For your own files the same message means a wrong relative path — ./utils is different from ../utils, and on Linux the case must match exactly even though Windows forgives it.
When Deleting node_modules Actually Helps
The universal advice is to delete node_modules and reinstall. It works often enough that people do it reflexively, but it is worth knowing when it is the right tool.
rm -rf node_modules package-lock.json
npm installIt genuinely helps when the tree is inconsistent — after switching branches with different dependencies, after a failed install left things half-written, or when a package was manually edited inside node_modules.
It does not help with ERESOLVE, which is a declared-version conflict and will recur identically on the next install.
Be deliberate about package-lock.json. Deleting it discards the exact resolved versions your project was tested against, and reinstalling may pull newer minor versions. Delete it when you suspect the lockfile itself is corrupt; keep it otherwise.
Two related commands worth knowing:
npm ci # clean install strictly from the lockfile — use in CI and deploys
npm cache clean --force # only when you suspect a corrupt cachenpm ci deletes node_modules and installs exactly what the lockfile specifies, refusing to update it. That reproducibility is exactly what you want on a server, and it is faster than npm install as well.
