devkult_
tools29converters34
home/blog/npm-eacces-permission-denied
npmnodepermissions

npm EACCES Permission Denied: Fix Global Installs Without sudo

npm error code EACCES
npm error syscall mkdir
npm error path /usr/local/lib/node_modules/typescript
npm error errno -13
npm error Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/typescript'

npm install -g writes to npm's global prefix. If Node was installed system-wide — from the official installer or a Linux package — that directory belongs to root, and your user can't write to it.

The tempting fix, sudo npm install -g, works, and is the one to avoid: it runs every install script of every package, and its dependencies, as root. Here are the fixes that don't need it.

Fix 1: use a Node version manager (best)

Version managers install Node inside your home directory, so global packages land somewhere you own:

# nvm (macOS, Linux, WSL)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
nvm install --lts
npm install -g typescript   # no sudo needed

fnm and Volta work the same way and are faster to switch. You also get easy switching between Node versions per project. Read any install script before piping it to a shell.

Fix 2: point npm's global prefix at your home directory

If you want to keep the system Node:

mkdir -p ~/.npm-global
npm config set prefix ~/.npm-global

Then add the new bin directory to your PATH in ~/.bashrc, ~/.zshrc or equivalent:

export PATH="$HOME/.npm-global/bin:$PATH"

Open a new shell, and npm install -g works without sudo.

Fix 3: skip global installs

Many tools don't need to be global. npx runs a package without installing it globally, and project-local dev dependencies keep everyone on the same version:

npx create-vite@latest my-app
npm install --save-dev typescript && npx tsc --version

"Your cache folder contains root-owned files"

npm error Your cache folder contains root-owned files, due to a bug in
npm error previous versions of npm which has since been addressed.

This one is the aftermath of an earlier sudo npm …: files in ~/.npm belong to root. npm prints the exact command to fix it; it amounts to giving the folder back to your user:

sudo chown -R "$(id -u):$(id -g)" ~/.npm

The same applies to a project's node_modules if it was ever installed with sudo — delete it and reinstall as yourself.

On Windows

The Windows equivalent is usually EPERM: operation not permitted, and the cause is different: a file locked by an editor, a running dev server or antivirus. Close what's holding the folder and retry, rather than running the terminal as Administrator.

For what the permission bits on these directories mean, see chmod 755 vs 644 and the chmod calculator. Hitting dependency conflicts instead? That's npm ERESOLVE.

More from the blog