Overview & Root Cause Summary: The error
npm ERR! code EACCES syscall access '/usr/local/lib/node_modules' - Error: EACCES: permission deniedoccurs when attempting to install global npm packages without root privileges into a system-owned directory, or when previously usingsudo npm installcorrupted the permissions of your local~/.npmcache.
Understanding the Root Causes
- System-Level Global Directory: By default, Node.js packages installed via system installers place global binaries in root-protected directories (such as
/usr/local/lib/node_modulesor/usr/lib/node_modules). - Permission Corruption from Sudo: Executing
sudo npm installtransfers ownership of internal cache files in~/.npmtoroot, preventing standard user write access. - Shared Multi-User Environments: Systems where developer user accounts lack write permissions to global system PATH directories.
Step 1: Quick Fix (Change npm’s Default Global Directory)
The officially recommended solution by npm is to configure a dedicated global directory in your home directory.
# Create a directory for global installations
mkdir -p ~/.npm-global
# Configure npm to use the new directory path
npm config set prefix '~/.npm-global'
# Add the new directory to your PATH (for ~/.zshrc or ~/.bashrc)
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.zshrc
# Reload your shell configuration
source ~/.zshrc
Step 2: Reclaim Ownership of ~/.npm and Cache Directories
If previous commands run with elevated privileges corrupted your cache ownership, reset them to your user account.
# Fix ownership of the ~/.npm cache directory
sudo chown -R $(whoami) ~/.npm
# Fix ownership of the global prefix directory if manually created
sudo chown -R $(whoami) ~/.npm-global
# Clear any corrupted cache artifacts
npm cache clean --force
Step 3: Alternative Approach (Use NVM or fnm)
Using a Node version manager isolates all global packages inside your user directory, eliminating root permission requirements completely.
# Install NVM (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# Source NVM in your current terminal session
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Install and switch to the latest LTS version of Node.js
nvm install --lts
nvm use --lts
Verification & Testing Steps
Verify that you can install global npm packages without using sudo and execute their binaries.
# Test global package installation without sudo
npm install -g serve
# Verify that the newly installed binary is available in PATH
which serve
serve --version
Summary Comparison Table
| Troubleshooting Approach | Security Impact | Setup Complexity | Recommended Context |
|---|---|---|---|
Custom Global Prefix (~/.npm-global) |
High (No root execution) | Low (2 commands) | Standalone Node.js system installs |
| Node Version Manager (NVM / fnm) | High (Full user isolation) | Low to Medium | Active web developers & multi-project environments |
Fix Ownership (chown -R) |
Moderate | Low (1 command) | Repairing existing corrupted ~/.npm caches |
Running with sudo (Not Recommended) |
Dangerous (Security risk) | Zero | Strongly discouraged (Causes recurring breakage) |
Leave a Reply