Node Setup for Macs

I use Macs, and I have a lot of Node projects on my Macs. Those projects don't all use the same version of Node, so I need to have multiple versions installed. I also want to have a "system" version of Node installed. I'm really happy with how I have my Macs set up to manage this for me. Here's how my setup works.

Nave

First thing I do, before I have any versions of Node installed, is install nave. Nave is a tool that allows you to install and manage different versions of Node. Nave intends to solve your entire multiple-versions-of-Node problem, but I don't use it for that. I use it solely to manage my system-wide version of Node -- the version that will run when I haven't opted to use a project-specified version (more on that later).

Nave is simply a bash script, and you can install it in one of the recommended ways, but what I do is download the script and save it on my system like this:

curl -s https://raw.githubusercontent.com/isaacs/nave/master/nave.sh > /usr/local/bin/nave 
chmod 755 /usr/local/bin/nave

Now I can use nave to install my system-wide version of Node.

System-Wide Node

This is a pair of commands that I can re-run any time I want to update my system-wide version of Node.

# where <version> can be a version like 12.4.1,
# or just 12.4, or just 12
# or it can be a string,
# like lts (meaning long-term support),
# or lts/erbium (code name for v12 lts)

nave install <version>
nave usemain <version>

Node Version Manager

Now that a system-wide Node is installed, I will install my version manager, nvm and an automatic version switcher that uses nvm, avn.

Nvm is similar to (and an alternative to) nave. Once installed, nvm is exposed as a shell function (functionally the same as the way nave is a bash script) that allows you to install multiple versions of Node and switch between them by manipulating your shell environment.

You can either explicitly specify a Node version when you run nvm use <version> or you can use an rc file named .nvmrc to specify the version of Node. The contents of .nvmrc can be a version number (full or partial) or a string (like "lts" or "lts/<codename") -- similar to nave. When you run nvm use nvm will use the version specified in the .nvmrc file in the current directory or the closest parent directory.

Avn, together with its companion plugin avn-nvm, will automatically look for an .nvmrc file every time you change directories and then change the Node version, if necessary. This is the key to maintaining your sanity when you have tons of Node projects running different versions of Node!

# Install nvm v0.35.2 (current latest)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
# You'll need to exit and re-open your terminal for the installation to take effect.

# Install avn and avn-nvm
# Make sure we're using the system-wide Node
nvm use system
npm install -g avn@latest avn-nvm@latest
avn setup

.nvmrc

After I have all that tooling set up, it's time to add rc files.

First, I add an .nvmrc in my $HOME directory that will be used to switch to the system-wide version Node whenever I'm in a directory that doesn't otherwise specify an alternative version.

# contents of $HOME/.nvmrc
system

Then in each project, I add an .nvmrc that specifies the lts or major version of Node that the project requires.

# example project .nvmrc
lts/erbium

This project-level `.nvmrc` should be committed to version control so that everyone on your team can use the same Node version seamlessly.

Before nvm use will work, you need to install the version of Node you want to use: for the above example, nvm install lts/erbium. After installation, you can test that everything is working by changing directories in your terminal and reviewing the terminal messages.

~ $ cd ~/code/test-project
avn activated lts/erbium via .nvmrc (avn-nvm v12.14.0)
~/code/test-project $ cd
avn activated system via .nvmrc (avn-nvm system: v12.14.1)
~ $ 
magic