I'm writing this post since there were a lot of guides online on how to set up NPM so you can do npm install -g
(that is, a global NPM install) on macOS or Linux without superuser privileges, but all those guides recommended a rather strange directory structure, such as a very strange looking ~/.npm
directory loose in your home folder. This is a bad idea for a several reasons.
In this article I intend to show the very simple steps to set it to a much better location of ~/.local
. This follows conventions and plays nice with many different applications, on both Linux-based systems, and macOS. 1
When npm
tries to install to globally, it tries to install it's packages to the sensible location of /usr/local/
. When you aren't a super user, this gives the warning checkPermissions Missing write access to /usr/local/lib
and error Error: EACCES: permission denied, access '/usr/local/lib'
and fails. Other package installers (such as Python's pip
) already ship, at least on Ubuntu, with a concept of a user-specific local directory of ~/.local/
to replace the global /usr/local/
to avoid such warnings.
Thus, let's just reuse this existing convention.
Step 1: Configure NPM
npm config set prefix ~/.local
Now NPM will install your global executables to ~/.local/bin
, and the libraries to ~/.local/lib/node_modules/
Step 2: Add ~/.local/bin
to your path
If you haven't already, open up the conf file of your favorite shell (such as ~/.bashrc
for Bash), and add in:
PATH=~/.local/bin/:$PATH
That's it. You're done.
Now, for why we are doing it this way instead of the incredibly common suggestions online of ~/.npm
. The most obvious is convention: other applications use ~/.local
also. However, ~/.npm
is particularly a terrible choice. Whatever you do, DON'T USE ~/.npm/ as your user installation directory. Why is ~/.npm
such a bad choice? ~/.npm
is the default npm cache directory! Thus, if you clear the cache, you'd wipe your modules too. You can check to see what your cache directory is with npm config ls -l | grep cache
.
Now can anyone tell me why this isn't the default, and why there's so much misinformation about this online?