Back

How to Fix EACCES: Permission Denied in npm

How to Fix EACCES: Permission Denied in npm

You run npm install -g to install a CLI tool, and instead of a clean install, you get this:

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

This npm EACCES error is one of the most common Node.js permission errors developers hit on macOS and Linux. Here’s why it happens and how to fix it properly.

Key Takeaways

  • The EACCES error occurs because npm tries to write to a root-owned directory like /usr/local/lib/node_modules, which your user account can’t access.
  • The recommended fix is installing Node.js through a version manager like nvm, which places everything inside your home directory.
  • Alternatively, you can configure npm to use a user-owned global directory by changing its prefix and updating your PATH.
  • Avoid sudo npm install -g — it causes long-term permission issues and introduces security risks.
  • For one-off CLI usage, npx runs packages without requiring a global install at all.

Why npm Permission Denied Errors Happen

When you run npm install -g, npm writes to a system-level directory like /usr/local/lib/node_modules. If you installed Node.js using an official installer or a system package manager, that directory is typically owned by root. Your regular user account doesn’t have write access to it, so the install fails.

This is a security feature of Unix-based systems, not a bug. The fix isn’t to override those protections — it’s to give npm a location your user already owns.

Important distinction: This article covers global install permission errors. If you’re seeing permission errors inside a local project’s node_modules folder, the cause is different — usually a file ownership mismatch in your project directory.

Fix npm Global Install Permissions: Two Safe Approaches

npm officially recommends using a Node version manager like nvm to avoid EACCES errors entirely. When nvm installs Node, it places everything inside your home directory — a location your user owns by default. No root access needed, ever.

Install nvm:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/HEAD/install.sh | bash

Then install Node:

nvm install --lts

After that, npm install -g works without sudo or permission changes. As a bonus, nvm lets you switch between Node versions per project — something no other fix offers.

Note: If you already have a custom npm prefix configured, nvm manages its own prefix internally. Don’t combine both approaches in the same environment, as they can conflict.

Option 2: Configure a User-Owned npm Global Directory

If you’d rather not use nvm, you can redirect npm’s global install location to a directory your user owns. This is the alternative described in the official npm docs.

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

Then add the bin directory to your PATH. For bash, add this to ~/.profile or ~/.bashrc:

export PATH=~/.npm-global/bin:$PATH

For zsh, add the same line to ~/.zshrc, then reload:

source ~/.zshrc

Verify it works by installing a package without sudo:

npm install -g npm-check-updates

What About sudo npm install -g?

Avoid it. Running sudo with npm installs files owned by root, which creates further permission problems down the line and introduces real security risks — a malicious or compromised package runs with elevated privileges. It’s a short-term workaround that makes things worse.

A Quick Alternative: Use npx Instead

If you only need a CLI tool occasionally, you may not need a global install at all. npx runs packages without installing them globally, using a local package or fetching one temporarily:

npm create vite@latest

No permissions required, no global directory involved.

Which Fix Should You Use?

SituationBest Approach
Developer managing multiple projectsnvm
Single machine, no version switching neededCustom npm prefix
One-off CLI tool usagenpx

Conclusion

The root cause of npm install -g EACCES errors is almost always the same: npm is trying to write to a root-owned directory. Fix that mismatch at the source — either by using nvm or by pointing npm to a directory you own — and the error disappears for good.

FAQs

You can, but you shouldn't. Using sudo installs packages owned by root, which leads to further permission issues when npm later tries to update or remove them as your regular user. It also exposes your system to security risks, since any install script runs with elevated privileges. Use nvm or a custom prefix instead.

Global installs write to system directories like /usr/local/lib/node_modules, which are owned by root on most systems. Local installs write to a node_modules folder inside your project directory, which you already own. That's why npm install works fine locally but fails globally without proper configuration.

Yes, packages previously installed under the old prefix won't be available from the new one. You'll need to reinstall them in the new location. List your old globals with npm list -g --depth=0 before changing the prefix, then reinstall them once the new directory is set up and your PATH is updated.

Generally no. Windows uses a different permission model, and npm's default global install path on Windows is already inside the user's AppData folder. EACCES errors are almost exclusive to macOS and Linux, where Unix-style file ownership controls write access to system directories like /usr/local.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay