Problem

When running npm install -g to install packages globally, you encounter:

1
2
3
4
5
npm ERR! code EACCES
npm ERR! syscall access
npm ERR! path /usr/local/lib/node_modules
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied

Root Cause

npm tries to install global packages in system directories that require elevated permissions. Using sudo works but creates security risks and file ownership issues.

Solution

  1. Create a directory for global installations:
1
mkdir ~/.npm-global
  1. Configure npm to use the new directory:
1
npm config set prefix '~/.npm-global'
  1. Add the new directory to your PATH:

For bash users, add to ~/.bashrc or ~/.bash_profile:

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

For zsh users, add to ~/.zshrc:

1
export PATH=~/.npm-global/bin:$PATH
  1. Reload your shell configuration:
1
source ~/.zshrc  # or source ~/.bashrc
  1. Test with a global install:
1
npm install -g typescript

Option 2: Fix Permissions (Alternative)

If you prefer keeping the default location:

1
2
3
sudo chown -R $(whoami) /usr/local/lib/node_modules
sudo chown -R $(whoami) /usr/local/bin
sudo chown -R $(whoami) /usr/local/share

⚠️ Warning: This changes ownership of system directories and may affect other tools.

Verification

After applying either fix, verify it works:

1
2
npm install -g cowsay
cowsay "npm is working!"

You should see the installation complete without errors and be able to run the installed command.

Prevention

  • Always use Option 1 (change npm prefix) for new setups
  • Add the PATH export to your dotfiles repository
  • Document this in your project README if teammates encounter it
  • Works for: npm, pnpm, yarn global installations
  • Platforms: macOS, Linux (Ubuntu, Debian, etc.)
  • Does NOT apply to: Windows (uses different global paths)