Blog
3 min read

npm EACCES: Permission Denied — Fix It Without sudo

EACCES means npm tried to write somewhere your user isn't allowed to — usually the global packages folder after Node was installed with sudo or a system package. Why sudo npm is the wrong fix, and the right ones: a Node version manager or a user-owned global prefix.

npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /usr/local/lib/node_modules/some-package
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/some-package'

EACCES means "access denied": npm tried to create or change a file in a folder your user account doesn't have permission to write to. It almost always happens with global installs (npm install -g ...).

Why it happens

Global packages go into a system folder like /usr/local/lib/node_modules or /usr/lib/node_modules. If Node.js was installed with the system package manager or the official installer, that folder is often owned by root, not you. (Linux file permissions)

Don't fix it with sudo

The tempting fix is:

sudo npm install -g some-package   # don't

Problems with that:

  • Security — package install scripts then run as root, with full control of your machine. A malicious or compromised package can do anything. (npm supply chain security)
  • More permission errors later — files created by root in your project or cache break future non-sudo commands.
  • Tools can't update themselves — anything installed this way (including CLI tools like Claude Code via npm) can't auto-update without sudo. Anthropic's own docs warn against sudo npm install -g.

Fix 1 (best): use a Node version manager

A version manager installs Node.js inside your home folder, so global packages go somewhere you own. It also lets you switch Node versions per project.

Popular choices: nvm (macOS/Linux), fnm (fast, cross-platform), nvm-windows, or Volta.

With nvm:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
# open a new terminal
nvm install --lts
npm install -g some-package   # no sudo, no error

Check the nvm project page for the current install command and version.

Fix 2: change npm's global folder

If you'd rather keep your current Node install, point npm's global folder at one you own:

mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global

Then add it to your PATH in ~/.zshrc or ~/.bashrc:

export PATH="$HOME/.npm-global/bin:$PATH"

Open a new terminal and global installs work without sudo. (Command not found and the PATH variable)

Fix 3: don't install globally at all

Many tools don't need a global install. Run them with npx, which downloads and runs a package on demand:

npx create-vite@latest my-app

Or install the tool as a dev dependency in your project and run it through an npm script.

If the error is inside your project or cache

EACCES: permission denied, open '/Users/you/.npm/_cacache/...'
EACCES: permission denied, unlink '/Users/you/my-app/node_modules/...'

Usually some files are owned by root because of an earlier sudo npm. Take ownership back:

sudo chown -R $(whoami) ~/.npm
sudo chown -R $(whoami) ./node_modules

(This one-time sudo is fine — it's fixing ownership, not running package scripts.)

On Windows

EACCES or EPERM on Windows usually means a file is locked — open in an editor, being scanned by antivirus, or used by a running dev server. Close running processes and retry. Running the terminal as Administrator works around it but isn't a habit worth forming.

Installing tools like Claude Code

For CLI tools that offer their own installer, prefer it over npm -g. Claude Code's native installer, for example, puts everything in your home folder and updates itself — no permissions to fight. (How to install Claude Code)


EasySpawn gives you a server where Node.js and your tools are already set up correctly for your user, so permission errors don't eat your afternoon. See how it works or join the waitlist.

Related: npm ERR! code ENOENT · What Are npm and package.json? · Linux File Permissions · How to Install Claude Code

Keep reading