npm EACCES: Permission Denied When Installing Global Packages
This error matches known, documented patterns with reliable solutions.
Quick Fix (Most Common Solution)
- Create a directory for global npm packages in your home folder
- Configure npm to use that new directory: npm config set prefix '~/.npm-global'
Seeing "npm ERR! code EACCES"? This error can be frustrating, but it's usually fixable. It typically affects your development workflow or system. Below you'll find clear, step-by-step solutions to resolve this issue.
What This Error Means
npm's global package directory is owned by root, not your current user. Attempting to install global packages writes to a system directory that requires elevated permissions. The correct fix is to change npm's prefix to a user-owned directory, not to use sudo.
Frequently documented in developer and vendor support forums.
Not affiliated with browser, OS, or device manufacturers.
New here? Learn why exact error messages matter →
Common Causes
- npm's global directory (/usr/local/lib or /usr/lib) is owned by root
- Using sudo npm install -g previously created root-owned files that block future non-sudo installs
- System Node.js installed via apt or yum has root-owned npm directories
How to Fix
- Create a directory for global npm packages in your home folder
- Configure npm to use that new directory: npm config set prefix '~/.npm-global'
- Add the new directory to PATH in your shell profile
- Source the profile file and reinstall the failing package
Last reviewed: June 2026 How we review solutions
Didn't fix it? Get a personalised solution
Environment-Specific Commands
Linux / macOS — Change npm global directory
mkdir ~/.npm-globalnpm config set prefix '~/.npm-global'echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.profilesource ~/.profilenpm install -g [package-name]
Linux / macOS — Use nvm instead (recommended long-term fix)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bashsource ~/.nvm/nvm.shnvm install --ltsnvm use --ltsnpm install -g [package-name]
Quick Diagnostic Path
- If npm config get prefix shows /usr or /usr/local → Change prefix to user directory: npm config set prefix '~/.npm-global' then add to PATH
- If Using nvm but still seeing EACCES → Run 'nvm use [version]' — you may have switched to a system Node.js outside nvm
- If Error path contains /root/ → Running as root user. Switch to a non-root user for all development work.
If This Still Fails, Check
- macOS with Homebrew Node: run brew reinstall node to reset permissions, or switch to nvm
- WSL2: ensure your project is inside the Linux filesystem (/home/user/) not the Windows mount (/mnt/c/) — Windows-mounted drives ignore Linux permission rules
- After fixing: old global packages in the root-owned directory still exist there. Reinstall each needed package from the new prefix.
Diagnose and fix npm global permission denied
# Check current npm prefix (if /usr or /usr/local — that is the problem)
npm config get prefix
# Fix: change prefix to user-owned directory
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.profile
source ~/.profile
# Verify: prefix is now in your home directory
npm config get prefix
# Expected: /home/yourname/.npm-global
# Test global install
npm install -g npm@latestCI/CD Considerations
Npm Eacces Permission Denied in Node.js CI: Build vs Runtime Environment Gaps
Npm Eacces Permission Denied that appears only in CI or only in production usually traces to a gap between the build environment and the runtime environment. Node.js applications built on one Node version and run on another frequently encounter this class of error.
The standard preventive: pin Node version in both the build pipeline and the runtime image using the same identifier — for example, node:20.11.0-alpine rather than node:20-alpine. The minor version matters because V8 updates within minor releases can affect runtime behavior. For TypeScript projects, the compiled JavaScript must target the runtime Node version's supported JavaScript features — check tsconfig.json's target and lib settings. Native modules (compiled with node-gyp) must be compiled for the runtime architecture and Node version, not the build machine's — use npm rebuild in the runtime Dockerfile stage after copying node_modules. Environment variables available during npm run build (like NODE_ENV) affect bundling behavior and may produce different output than expected in production.Optional follow-up
Some users ask whether saving fixes for recurring errors would be useful when the same issue appears again.
Was this explanation helpful?
Frequently Asked Questions
Why shouldn't I just use sudo npm install?
Using sudo creates root-owned files inside node_modules that block all future non-sudo npm operations. It creates an escalating cycle of permission problems.
Does using nvm fix this permanently?
Yes. nvm installs Node.js in your home directory so npm global packages also land in a user-owned location. No root access is ever needed for global installs.
What if I already used sudo and broke things?
Fix ownership: sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share} — then change the prefix as described above.
Also Known As
- Node.js error
- Node runtime error
- JavaScript server error
- Node exception
Common Search Variations
- "node js error fix"
- "node command not working"
- "node app crashing"
- "javascript server error solution"
- "node runtime crash fix"
- "how to debug node error"
Related Errors
Still Stuck?
Paste a different error message or upload a screenshot to get help instantly.