Skip to content
Commitpedia
Log in Join & edit

Fix: npm ERR! EACCES permission denied

npm cannot write to a directory it needs: the global install location, its cache in ~/.npm, or a node_modules owned by root. Fix the ownership or install globals into a user-owned prefix instead of using sudo.

Drafted with AI from official documentation. Scripts were run in a test environment and repository links verified. Awaiting a human check. Did it work for you? Last edited Outdated?

Edit history of Fix: npm ERR! EACCES permission denied: 1 recorded edit
Edit history · 1 edit
Type
Article
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Reading
3 min
npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /usr/local/lib/node_modules/typescript
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/typescript'
npm ERR!
npm ERR! Your cache folder contains root-owned files, due to a bug in
npm ERR! previous versions of npm which has since been addressed.

EACCES is the operating system saying that the user running npm has no permission to create or change a file at the path shown. Read the path line: it tells you which of the three usual directories is the problem.

Cause 1: installing a global package into a root-owned prefix

On Linux and on Macs where Node came from an installer, globals go to /usr/local/lib/node_modules or /usr/lib/node_modules, which only root can write. npm’s own documentation recommends either a version manager, which installs Node into your home directory, or changing npm’s prefix to a folder you own. Do not use sudo npm install -g; it creates root-owned files that cause this very error later.

Check before you run this

  • Downloads a file and runs it straight away. Open the URL and read the script first.
  • Runs with administrator rights. Make sure you understand every line.
# Option A (recommended): a Node version manager such as nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# open a new terminal, then
nvm install --lts
npm install -g typescript        # now lands in ~/.nvm, no sudo

# Option B: keep your Node, move the global prefix into your home
mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc   # or ~/.zshrc
source ~/.bashrc
npm install -g typescript

Check the exact nvm version and URL on the nvm README before running the installer; piping a script to bash is only acceptable from a source you have verified.

Cause 2: root-owned files in the npm cache

If sudo npm was ever used, ~/.npm may contain files owned by root and every later install fails while writing the cache. npm prints the fix in the error itself: give the cache back to your user.

Check before you run this

  • Runs with administrator rights. Make sure you understand every line.
sudo chown -R "$(id -u):$(id -g)" ~/.npm
npm cache verify

Cause 3: node_modules or the project folder is owned by someone else

A project cloned or built with sudo, copied from another user, or created inside a Docker volume can leave node_modules or package-lock.json owned by root. Fix the ownership of the project, not of the system.

Check before you run this

  • Runs with administrator rights. Make sure you understand every line.
ls -ld . node_modules package-lock.json
sudo chown -R "$(id -u):$(id -g)" .
npm install

Careful: run that chown -R only inside your project directory. Running it on /, /usr or your whole home with the wrong user breaks the system.

Cause 4: a read-only or noexec location

Installing into a mounted network share, a read-only Docker layer, or a CI cache directory you do not own also gives EACCES. Build in a writable path (WORKDIR /app owned by the user in your Dockerfile; USER node after chown) or set npm_config_cache to a writable directory in CI.

Check that it is fixed

Check before you run this

  • Runs with administrator rights. Make sure you understand every line.
npm config get prefix         # a directory you own
npm install -g npm@latest     # a global install that needs no sudo
npm ls -g --depth=0

When it is not what you think

  • EACCES: permission denied, open '/path/.env' at runtime is your application failing to read a file, not npm.
  • EPERM: operation not permitted on macOS and Windows is a different code: a file is locked by another process or blocked by antivirus or by macOS privacy settings on folders such as Documents.
  • ENOENT means a file is missing, often because npm install was run in the wrong directory.
  • EACCES when starting your app on port 80 or 443 is the kernel refusing a privileged port, nothing to do with npm; use a port above 1023 or a reverse proxy.

Official documentation

Did this work for you?

No votes yet. Be the first.

If it did not work, the report form below tells the editors what went wrong.

See also

Repos in the wild

  • Node.js nodejs/node The source of the Node.js runtime: a JavaScript engine (V8) plus APIs for files, networking, processes and more, used to run JavaScript outside the browser. GitHub
  • Express (expressjs/express) expressjs/express A minimal and flexible web framework for Node.js, built around routes and middleware, and the foundation of countless APIs and other frameworks. GitHub

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. Dominik +3,792 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?