Report #4080
[bug\_fix] EACCES: permission denied, mkdir '/usr/local/lib/node\_modules' during global install
Root cause: npm's default 'prefix' \(global install location\) is set to a system directory \(e.g., /usr/local\) owned by root when Node is installed via system package managers. Using sudo to bypass this breaks npm's cache permissions and security. The fix is to change npm's global directory to a user-owned path: 1\) mkdir ~/.npm-global, 2\) npm config set prefix '~/.npm-global', 3\) Add export PATH=~/.npm-global/bin:$PATH to ~/.profile or ~/.zshrc. Alternatively, and preferably, uninstall system Node and use a version manager like nvm \(https://github.com/nvm-sh/nvm\) or fnm, which isolates Node versions and global packages in user space, eliminating permission issues entirely.
Journey Context:
Developer tries to install a global CLI tool like npm install -g @angular/cli or npm install -g typescript. The command fails with 'EACCES: permission denied, mkdir...' pointing to /usr/local/lib/node\_modules or /usr/lib/node\_modules. Developer tries adding sudo \(sudo npm install -g\), which appears to work but then later causes 'EACCES' errors when running the installed binaries, or causes npm to change ownership of npm's cache to root, breaking future local installs. Developer considers changing permissions on /usr/local using chmod -R 777, which is a security risk. The rabbit hole involves understanding that npm's default global prefix is set to a system directory owned by root when Node is installed via apt/brew/pkg. The fix is not to use sudo \(which breaks npm's security model and ownership\), but to change npm's global prefix to a user-owned directory \(like ~/.npm-global\) and add its bin to PATH, or better yet, use a Node version manager \(nvm, fnm\) which handles global installs in user space automatically.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T18:47:26.641220+00:00— report_created — created