Skip to content

Instantly share code, notes, and snippets.

@rcugut
Forked from DanHerbert/fix-homebrew-npm.md
Last active October 10, 2025 20:15
Show Gist options
  • Save rcugut/c7abd2a425bb65da3c61d8341cd4b02d to your computer and use it in GitHub Desktop.
Save rcugut/c7abd2a425bb65da3c61d8341cd4b02d to your computer and use it in GitHub Desktop.
Install node & npm on Mac OS X with Homebrew

Fixing npm On Mac OS X for Homebrew Users

Explanation of the issue

If you're a Mac Homebrew user and you installed node via Homebrew, there is a major philosophical issue with the way Homebrew and NPM work together. If you install node with Homebrew try to do npm update npm -g, you will see error like this:

$ npm update npm -g
npm http GET https://registry.npmjs.org/npm
npm http 304 https://registry.npmjs.org/npm
npm http GET https://registry.npmjs.org/npm/1.4.4
npm http 304 https://registry.npmjs.org/npm/1.4.4
npm ERR! error rolling back Error: Refusing to delete: /usr/local/bin/npm not in /usr/local/lib/node_modules/npm
npm ERR! error rolling back     at clobberFail (/usr/local/Cellar/node/0.10.26/lib/node_modules/npm/lib/utils/gently-rm.js:57:12)
npm ERR! error rolling back     at next (/usr/local/Cellar/node/0.10.26/lib/node_modules/npm/lib/utils/gently-rm.js:43:14)
npm ERR! error rolling back     at /usr/local/Cellar/node/0.10.26/lib/node_modules/npm/lib/utils/gently-rm.js:52:12
npm ERR! error rolling back     at Object.oncomplete (fs.js:107:15)
npm ERR! error rolling back  [email protected] { [Error: Refusing to delete: /usr/local/bin/npm not in /usr/local/lib/node_modules/npm] code: 'EEXIST', path: '/usr/local/bin/npm' }
npm ERR! Refusing to delete: /usr/local/bin/npm not in /usr/local/lib/node_modules/npm
File exists: /usr/local/bin/npm
Move it away, and try again. 

npm ERR! System Darwin 13.1.0
npm ERR! command "/usr/local/Cellar/node/0.10.26/bin/node" "/usr/local/bin/npm" "update" "npm" "-g"
npm ERR! cwd /Users/dan/Google Drive/Projects/dotfiles
npm ERR! node -v v0.10.26
npm ERR! npm -v 1.4.3
npm ERR! path /usr/local/bin/npm
npm ERR! code EEXIST
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /Users/dan/Google Drive/Projects/dotfiles/npm-debug.log
npm ERR! not ok code 0

There's an NPM bug open for this exact problem and a long thread that is still actively being debated, but the summary is that npm is its own package manager and it is therefore better to have npm manage itself and its packages instead of letting Homebrew do it. Also, using the Homebrew version of npm requires sudo to install global packages. That's also a very bad idea.

Solution

This solution fixes the error caused by trying to run npm update npm -g. Once you're finished, you also won't need to use sudo to install npm modules globally.

First, remove globally installed node modules. This step may not be necessary, but I do it to ensure my machine is clean before continuing. This step will be very specific to your setup. I've provided the one I ran as an example only. All other steps are completely copy/paste verbatim after this one.

sudo npm uninstall -g grunt-cli yo uglify-js nodemon jshint http-server bower

Next, run the following commands to remove node, re-install it with the right defaults, install npm as its own module, and configure the location for global npm modules to go.

brew uninstall node
brew install node --without-npm
echo prefix=~/.node >> ~/.npmrc
curl -L https://www.npmjs.org/install.sh | sh

Node and npm should be correctly installed at this point. The final step is to add ~/.node/bin to your PATH so commands you install globally are usable. I added this line to my ~/.path script, which gets called via ~/.bash_profile. If you want to see a full example you can check out my dotfiles repo on github.

export PATH="$HOME/.node/bin:$PATH"

Now you should re-install any global node packages again. As an example, these are the ones I know I'll use:

npm install -g grunt-cli http-server uglify-js jshint bower yo nodemon
@hughsw
Copy link

hughsw commented Jun 14, 2017

As of 2017-06-14 the steps above fail to install npm. It appears that the installation puts in symlinks that point into the TMP directory where the package got unpacked (and later deleted). Here are command showing the environment and the problem:

:~ hugh$ printenv|grep -i npm
PATH=/Users/hugh/bin:/usr/local/npm_packages/bin:/usr/local/opt/gnu-tar/libexec/gnubin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/opt/go/libexec/bin:/Users/hugh/work/go/bin
NODE_PATH=/usr/local/npm_packages/lib/node_modules:
NPM_PACKAGES=/usr/local/npm_packages

:~ hugh$ ls -la /usr/local/npm_packages/
total 0
drwxr-xr-x   2 hugh  admin   68 Jun 14 13:34 .
drwxr-xr-x  16 root  wheel  544 Jun 14 12:53 ..

:~ hugh$ cat ~/.npmrc
prefix=/usr/local/npm_packages
save-exact=true
progress=false

:~ hugh$ which npm

:~ hugh$ curl -L https://www.npmjs.com/install.sh | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6255  100  6255    0     0  11898      0 --:--:-- --:--:-- --:--:-- 11891
tar=/usr/local/opt/gnu-tar/libexec/gnubin/tar
version:
tar (GNU tar) 1.29
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by John Gilmore and Jay Fenlason.
install npm@latest
fetching: https://registry.npmjs.org/npm/-/npm-5.0.3.tgz
removed 1 package in 0.066s   # presumably removing the previous failure where I wasn't carefully scripting what I typed
/usr/local/npm_packages/bin/npm -> /usr/local/npm_packages/lib/node_modules/npm/bin/npm-cli.js
+ [email protected]
added 1 package in 2.204s
It worked

:~ hugh$ which npm

:~ hugh$ ls -la /usr/local/npm_packages/
total 0
drwxr-xr-x   6 hugh  admin  204 Jun 14 13:42 .
drwxr-xr-x  16 root  wheel  544 Jun 14 12:53 ..
drwxr-xr-x   3 hugh  admin  102 Jun 14 13:42 bin
drwxr-xr-x   2 hugh  admin   68 Jun 14 13:42 etc
drwxr-xr-x   3 hugh  admin  102 Jun 14 13:42 lib
drwxr-xr-x   3 hugh  admin  102 Jun 14 13:42 share

:~ hugh$ ls -la /usr/local/npm_packages/bin
total 8
drwxr-xr-x  3 hugh  admin  102 Jun 14 13:42 .
drwxr-xr-x  6 hugh  admin  204 Jun 14 13:42 ..
lrwxr-xr-x  1 hugh  admin   38 Jun 14 13:42 npm -> ../lib/node_modules/npm/bin/npm-cli.js

:~ hugh$ ls -la /usr/local/npm_packages/bin/../lib/node_modules/npm/bin/npm-cli.js
ls: /usr/local/npm_packages/bin/../lib/node_modules/npm/bin/npm-cli.js: No such file or directory

:~ hugh$ ls -la /usr/local/npm_packages/bin/../lib/node_modules/npm/bin/
ls: /usr/local/npm_packages/bin/../lib/node_modules/npm/bin/: No such file or directory

:~ hugh$ ls -la /usr/local/npm_packages/bin/../lib/node_modules/npm/
ls: /usr/local/npm_packages/bin/../lib/node_modules/npm/: No such file or directory

:~ hugh$ ls -la /usr/local/npm_packages/bin/../lib/node_modules/
total 8
drwxr-xr-x  3 hugh  admin  102 Jun 14 13:42 .
drwxr-xr-x  3 hugh  admin  102 Jun 14 13:42 ..
lrwxr-xr-x  1 hugh  admin   88 Jun 14 13:42 npm -> ../../../../../private/var/folders/fd/7j7f85712_535yytw45h9fj80000gn/T/npm.75082/package

@fasfsfgs
Copy link

@hughsw did you manage to fix or workaround this issue?

@jhyde
Copy link

jhyde commented Jun 28, 2017

Did you ever come up with a resolution to this problem? I'm running into the exact same issue.

@hughsw
Copy link

hughsw commented Jul 7, 2017

Yes, but not the way I intended. We switched to the latest node (8.1.2) and have not had trouble with the npm (5.0.3) that came with it.

The following is taken from the instructions I wrote for our team (with some stuff redacted). You will get a newer version of node than these instructions indicate.

Notes on prepping your Mac for Angular 4

We're upgrading to Angular 4.

This is a two-step process:

  • First you need to overhaul your dev environment on your Mac. This is disruptive because many steps are necessary, and node and npm are out of action for the duration.
  • Then you switch to a project configuration that uses Angular 4. This is relatively simple

Before removing tools

Before removing tools, be sure to shut down any instances of npm that you may be running in terminals/shells for the service or the server.

Grep for npm to verify that it's not running.

Example of a Verification Failure: you should not see any npm processes:

$ ps ax | fgrep npm
  848 s002  S+     0:00.30 npm   # npm running a server somewhere...
  843 s003  S+     0:00.37 npm   # npm running a server somewhere...
 6315 s006  R+     0:00.00 fgrep npm

Verification Success: you should only see the fgrep process

$ ps ax | fgrep npm
 6317 s006  S+     0:00.00 fgrep npm

Get rid of old versions of tools

Remove stuff and verify that it's gone.

Look at what Yarn has installed globally (your list will be different).

Note: You must use yarn global ... for managing globally installed packages.

$ yarn global ls
warning No license field
info "@angular/[email protected]" has binaries:
   - ng
info "[email protected]" has binaries:
   - node-gyp
info "[email protected]" has binaries:
   - node-pre-gyp
info "[email protected]" has binaries:
   - nodemon
✨  Done in 3.71s.

Remove all yarn-managed packages

Use the first part of the package name following "info" for the package name:

$ yarn global remove nodemon
[1/2] Removing module nodemon...
[2/2] Regenerating lockfile and installing missing dependencies...
warning No license field
success Uninstalled packages.
✨  Done in 5.46s.
$ yarn global remove node-pre-gyp
[1/2] Removing module node-pre-gyp...
[2/2] Regenerating lockfile and installing missing dependencies...
warning No license field
success Uninstalled packages.
✨  Done in 5.25s.
$ yarn global remove node-gyp
[1/2] Removing module node-gyp...
[2/2] Regenerating lockfile and installing missing dependencies...
warning No license field
success Uninstalled packages.
✨  Done in 5.33s.
$ yarn global remove @angular/cli
[1/2] Removing module @angular/cli...
[2/2] Regenerating lockfile and installing missing dependencies...
warning No license field
success Uninstalled packages.
✨  Done in 2.33s.

Verify that they're all gone, and that there's no binary (Yarn's or anyone else's around)

$ yarn global ls
warning No license field
✨  Done in 0.08s.

$ ng
-bash: ng: command not found

$ nodemon
-bash: /Users/hugh/.config/yarn/global/node_modules/.bin/nodemon: No such file or directory

I don't know why my two failure messages for ng vs nodemon are so different.

If you still have packages listed, or you still have a version of either ng or nodemon available, you will have to figure out why and get rid of them all. Regarding binaries, friends include:

$ which ng
$ which nodemon

Remove tools that npm manages

You may have tools globally installed and managed by npm. See if npm is managing tools:

$ npm list -g --depth=0
/usr/local/lib
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

If you have tools in a tree as above, you have to remove each of them with npm. Remove each tool, except npm itself. E.g.

npm uninstall angular-cli -g
npm uninstall mysql -g
npm uninstall nodemon -g
npm uninstall sequelize -g
npm uninstall sequelize-cli -g

Once npm list -g --depth=0 only shows npm itself, then remove npm:

npm uninstall npm -g

Remove tools from Brew

Remove node (and npm which it includes), yarn, and watchman from your Brew installation

$ brew ls yarn watchman node
/usr/local/Cellar/yarn/0.24.6/bin/yarn
/usr/local/Cellar/yarn/0.24.6/bin/yarnpkg
/usr/local/Cellar/yarn/0.24.6/libexec/bin/ (5 files)
/usr/local/Cellar/yarn/0.24.6/libexec/lib/ (2 files)
/usr/local/Cellar/yarn/0.24.6/libexec/package.json
/usr/local/Cellar/watchman/4.7.0/bin/watchman
/usr/local/Cellar/watchman/4.7.0/bin/watchman-make
/usr/local/Cellar/watchman/4.7.0/bin/watchman-wait
/usr/local/Cellar/watchman/4.7.0/libexec/bin/ (3 files)
/usr/local/Cellar/watchman/4.7.0/libexec/lib/ (11 files)
/usr/local/Cellar/watchman/4.7.0/share/doc/watchman-4.7.0/README.markdown
/usr/local/Cellar/node/8.1.2/bin/node
/usr/local/Cellar/node/8.1.2/etc/bash_completion.d/npm
/usr/local/Cellar/node/8.1.2/include/node/ (135 files)
/usr/local/Cellar/node/8.1.2/lib/dtrace/node.d
/usr/local/Cellar/node/8.1.2/libexec/bin/npm
/usr/local/Cellar/node/8.1.2/libexec/lib/ (3632 files)
/usr/local/Cellar/node/8.1.2/share/doc/ (3 files)
/usr/local/Cellar/node/8.1.2/share/man/man1/node.1
/usr/local/Cellar/node/8.1.2/share/systemtap/tapset/node.stp

Also run this:

$ brew ls npm

If the above command shows that you have npm intalled and managed by Brew, then you should include npm in the following commands that remove stuff; insert "npm" right before "node" in these commands.

$ brew uninstall yarn watchman  node
Uninstalling /usr/local/Cellar/yarn/0.24.6... (13 files, 3.4MB)
Uninstalling /usr/local/Cellar/watchman/4.7.0... (21 files, 428.9KB)
Uninstalling /usr/local/Cellar/node/8.1.1... (3,786 files, 45.9MB)

Verify that all of yarn, watchman, npm, and node are gone:

$ for p in yarn watchman node ; do brew ls $p ; done
Error: No such keg: /usr/local/Cellar/yarn
Error: No such keg: /usr/local/Cellar/watchman
Error: No such keg: /usr/local/Cellar/node

$ yarn
-bash: /usr/local/bin/yarn: No such file or directory

$ watchman
-bash: watchman: command not found

$ npm
env: node: No such file or directory

$ node
-bash: node: command not found

If you still have any of those commands available, you will have to figure out why and get rid of them all.

Install up-to-date tools

Update and Upgrade Brew

$ brew update   # be patient
...

$ brew upgrade   # be (very) patient
...

Do the above two commands again, just to be sure (it shouldn't take long).

Install node (and npm)

$ brew install node
==> Downloading https://homebrew.bintray.com/bottles/node-8.1.2.sierra.bottle.tar.gz
Already downloaded: /Users/hugh/Library/Caches/Homebrew/node-8.1.2.sierra.bottle.tar.gz
==> Pouring node-8.1.2.sierra.bottle.tar.gz
==> Using the sandbox
==> Caveats
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
==> Summary
 /usr/local/Cellar/node/8.1.2: 3,782 files, 45.9MB

Verify:

$ which node
/usr/local/bin/node
$ node --version
v8.1.2

$ which npm
/usr/local/bin/npm
$ npm --version
5.0.3

@hughsw
Copy link

hughsw commented Jul 7, 2017

Also, just today, I did an uninstall of the node that was installed via my above instructions. After the uninstall, it left npm installed, but unable to run due to there not being a node available. (I'm not sure if this is a manifestation of the original problem that this thread addresses).

The reason for the uninstall is that I was downgrading to node@6. The install of node@6 configured itself to not install a new npm. And now the orphan npm works using the node@6 that I installed. So, I now have node 6.11.0 and npm 5.0.3 (where the npm 5.0.3 was installed as part of node 8.1.2, but not removed when I uninstalled node 8).

@rcugut
Copy link
Author

rcugut commented Jul 13, 2017

True, there is a problem with the latest install of npm (probably >= 5.0). I stumbled over this today, with a fresh install.

I ended up hack-fixing this by manually copying the untarred contents of the npm tgz in /usr/local/npm_packages/node_modules/npm

I did an update to the gist above, to reflect this extra step.

Eventually, the initial issue that lead to this guide may have disappeared (i.e. fixed), and now it may work to install node with npm bundled, directly via homebrew. I didn't have time to give it a try.

@andredewaard
Copy link

andredewaard commented Dec 27, 2017

This doesn't work on High Sierra.

mkdir -p /usr/local/npm_packages outputs: mkdir: /usr/local/npm_packages: Permission denied
and
sudo chown -R `whoami` /usr/local outputs: chown: /usr/local: Operation not permitted

Saw something similar on Homebrew/brew#3228 (comment)

@jevgen
Copy link

jevgen commented Jan 8, 2018

You may need to fix permissions
sudo chown -R $(whoami) /usr/local/share/doc
before install.

@ran-dall
Copy link

I've been using this walkthrough for a while...
https://johnpapa.net/how-to-use-npm-global-without-sudo-on-osx/

@suvajit
Copy link

suvajit commented Jan 24, 2018

FInally my node/npm got resolved after much struggle !!
Thanks to your very well described process with proper anecdotes.

@SilencerWeb
Copy link

it doesn't work for me =( in the end when I'm trying to use npm install -g npm I have such error zsh: command not found: npm

@nolybom
Copy link

nolybom commented Mar 28, 2018

To fix the owner on high sierra run this...

sudo chown -R $(whoami) $(brew --prefix)/*

@MirelesCloud
Copy link

You're my hero. I've spent all day trying to get npm working. This finally worked. However, note that this step # move the extracted package in the correct place and rename to npm
mv package /usr/local/npm_packages/lib/node_modules/npm
turned out the following error
mv: rename package to /usr/local/npm_packages/lib/node_modules/npm: No such file or directory
I haven't been able to fix this.

@vukanac
Copy link

vukanac commented Apr 5, 2018

List and save if you need all previous packages (won't work if you have already removed node):

$ npm list -g

Remove global packages:
$ rm -rf /usr/local/lib/node_modules
$ rm -rf ~/.npm-packages/lib/node_modules/npm

Then just install node (latest) (with npm) with brew:
$ brew install node
$ node -v
$ npm -v // eg. 5.6.0

Test does it work without sudo:
$ npm install -g npm
$ npm -v // eg. 5.8.0

@w4-hojin
Copy link

w4-hojin commented Jun 12, 2018

Now, node LST is @8.
Even if we use node LTS, we can use yarn also.

@edPratt
Copy link

edPratt commented Mar 12, 2019

Since --without is deprecated, this no longer works. this worked for me

@idelendik
Copy link

brew prune has been replaced. Call brew cleanup instead.
Homebrew version: 2.2.2.

@idelendik
Copy link

brew install node --without-npm returns invalid option: --without-npm

Options have been removed from formula last year. brew install node is the way to get node and you’ll get npm with that. If you don’t want npm you could maintain a separate version of the node formula for yourself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment