# npm EACCES Permission Denied: Fix Global Installs Without sudo

```text
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:

```bash
# 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:

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

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

```bash
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:

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

## "Your cache folder contains root-owned files"

```text
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:

```bash
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](/blog/chmod-755-vs-644) and the [chmod calculator](/chmod/755). Hitting dependency conflicts instead? That's [npm ERESOLVE](/blog/npm-eresolve-unable-to-resolve-dependency-tree).
