[Fixed] npm ERR! code EACCES: permission denied, access ‘/usr/local/lib/node_modules’: Step-by-Step Troubleshooting Guide

Overview & Root Cause Summary: The error npm ERR! code EACCES syscall access '/usr/local/lib/node_modules' - Error: EACCES: permission denied occurs when attempting to install global npm packages without root privileges into a system-owned directory, or when previously using sudo npm install corrupted the permissions of your local ~/.npm cache.

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_modules or /usr/lib/node_modules).
  • Permission Corruption from Sudo: Executing sudo npm install transfers ownership of internal cache files in ~/.npm to root, 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

Discover more from Victor's room

Subscribe now to keep reading and get access to the full archive.

Continue reading