How to fix npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules' in npm

npmBEGINNERMEDIUMUpdated Dec 2, 2025ยท 316 views

npm cannot write to the global prefix because it is root-owned or locked. Move globals into your home (nvm/user prefix) or realign ownership once, then reinstall cleanly.

Quick fix

Fixes npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'

npm config get prefix
ls -ld $(npm config get prefix)/{lib/node_modules,bin}
  1. Inspect prefix and permissions
  2. Switch to nvm/fnm/asdf or a user prefix (preferred)
  3. Clean staging and cache
  4. Realign ownership once (if you administer the host)
npm โ€” error
npm config get prefix
ls -ld $(npm config get prefix)/{lib/node_modules,bin}
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'

What this error means

npm installs global packages into the prefix directory (default /usr/local/lib/node_modules) and links executables under prefix/bin. When those directories are owned by root or mounted read-only, a normal user cannot create or modify files, so npm aborts early with EACCES instead of leaving partially written packages. The issue appears when system Node was installed with sudo or a package manager, when prior sudo npm installs left root-owned artifacts, or when running inside Docker/CI as a non-root user against a root-owned filesystem. Windows/WSL users can also hit it if Defender or corporate EDR blocks writes to node_modules.

Typical symptoms

  • npm install -g fails immediately with EACCES on /usr/local/lib/node_modules
  • Command succeeds only with sudo/Admin privileges
  • npm config get prefix returns /usr/local or another root-owned path
  • Leftover .staging/.DELETE folders remain after failure
  • Global binaries missing from PATH after install attempt
  • In Docker/CI, non-root npm jobs fail while root works

Common causes

  1. System-wide Node install created root-owned prefix/bin directories
  2. Previous sudo npm installs left root-owned files blocking user writes
  3. Corporate or locked-down images mark /usr/local read-only to non-root users
  4. Homebrew or package-manager Node with drifted ownership in /usr/local or /opt/homebrew
  5. Docker/CI or WSL running npm as a non-owner of the mounted volume
  6. AV/EDR (Defender, CrowdStrike) holding locks on node_modules during install

How to fix "npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'"

1Inspect prefix and permissions
bash
npm config get prefix
ls -ld $(npm config get prefix)/{lib/node_modules,bin}

Confirm whether the prefix and bin are root-owned or read-only.

2Switch to nvm/fnm/asdf or a user prefix (preferred)
bash
# nvm example
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \ . "$NVM_DIR/nvm.sh"
nvm install --lts
# fallback user prefix
mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global
export PATH="$HOME/.npm-global/bin:$PATH"

Keep the PATH export in your shell profile so globals resolve.

3Clean staging and cache
bash
sudo rm -rf $(npm config get prefix)/lib/node_modules/.staging $(npm config get prefix)/lib/node_modules/.*.DELETE 2>/dev/null || true
npm cache clean --force

Removes root-owned temp folders that block retries.

4Realign ownership once (if you administer the host)
bash
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

Do this only on machines you control; avoid on shared hosts.

5Retry the install without sudo
bash
npm install -g <package>

Run with the user-owned prefix so npm can write normally.

6Address Windows/WSL file locks

If you see EPERM/EACCES on Windows paths, close VS Code/terminals that hold node_modules, add a Defender exclusion for your global prefix, and retry from an elevated PowerShell or with Developer Mode enabled for symlinks.

Advanced notes

In Docker/CI, either run npm as the image owner (often root) or set a user prefix inside the workspace volume to avoid root-owned /usr/local. On macOS Homebrew, ensure the brew user owns /usr/local or /opt/homebrew; permission drift there is common after OS upgrades. Avoid mixing sudo and user installs because it creates root-owned artifacts that keep failing future installs. Windows/WSL users should watch for Defender/EDR locks and enable Developer Mode to allow npm-created symlinks and temp files.

Frequently asked questions

What does "npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node" mean?
npm installs global packages into the prefix directory (default /usr/local/lib/node_modules) and links executables under prefix/bin. When those directories are owned by root or mounted read-only, a normal user cannot create or modify files, so npm aborts early with EACCES instead of leaving partially written packages. The issue appears when system Node was installed with sudo or a package manager, when prior sudo npm installs left root-owned artifacts, or when running inside Docker/CI as a non-root user against a root-owned filesystem.
How do I fix "npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node"?
npm cannot write to the global prefix because it is root-owned or locked. Move globals into your home (nvm/user prefix) or realign ownership once, then reinstall cleanly.
What causes "npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node"?
System-wide Node install created root-owned prefix/bin directories Previous sudo npm installs left root-owned files blocking user writes Corporate or locked-down images mark /usr/local read-only to non-root users
Is the "npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading