What is NVM ?

NVM - short for Node Version Manager - according to the description on its github page is described as a simple bash script to manage multiple active node.js versions. In other words nvm makes it possible to install multiple versions of node js on the same system.

Why NVM ?

With the very active release schedule for node js, it could be quite a pain to have to:

  • uninstall the current version of node running on the system
  • install the new version to test
  • maybe (or maybe not) uninstall the new version and revert to the previous version

NVM makes it very easy to install any version of node js. Same also can be said for its ability to switch between multiple versions of installed node js.

Also it makes it very easy to run - on the same system - two applications requiring very disimilar versions of node. Not to mention that uninstalling installed versions is a breeze!

In summary, NVM can come in quite handy no matter your current use of nodejs.

Installing NVM

The installation instructions for nvm are given on the github page but the TL;DR is given below:

# first we get the latest version of nvm
# it is assumed that curl is installed, of not wget is another option
nvm_version=`curl --silent https://api.github.com/repos/creationix/nvm/releases/latest | /usr/bin/awk '/tag_name/ { print $2 }' | /bin/sed 's/[",]//g'`

# now we install it
curl -o- https://raw.githubusercontent.com/creationix/nvm/$nvm_version/install.sh | bash

# you can check that it is installed by running
command -v nvm

Note

Running which nvm would not yield any result. Also if after running command -v nvm, no result is displayed then try sourcing the user's .bashrc file.

Installing a node version

It is possible to see a list of available versions of node js by running:

nvm ls-remote

At the time of writing, the latest boron long term release version is v6.11.0. We can install this simply by doing

nvm install v6.11.0
# after installation we'd need to activate it
nvm use v6.11.0

This node version in installed in the $HOME/.nvm/versions/node directory.

It is - as mentioned earlier - possible to install multiple versions of node js. To install another version (say the latest Argon LTS version - v4.8.3 at the time of writing):


nvm install v4.8.3

Switching to this new version is as simple as:

nvm use v4..83

And uninstalling a version:

nvm uninstall v6.11.0

Getting Fancy

When running on a VPS (digital ocean for instance), it would be great to have a single version of node globally available and one which would not be affected anytime a switch is made between versions. As an illustration, it would not be out of place to install nvm and node as the root user on a VPS and have the www-data user need access to the node install to run a deployed application.

An easy solution would be to install nvm and node for the www-data user. While this works, it might lead to confusion about the location of the active node binary. A more elegant solution involves creating a central location for the node path, copying the default node directory to this path, and watching and updating the directory when changes are made. These steps are given below:

# all commands are run as root except where stated otherwise

# create a directory that will serve as our node path
mkdir -p /usr/local/nvm
chmod -R 755 /usr/local/nvm

# install the version of node that would be globally available
nvm install v6.11.0

# this node version is now installed at:
# /root/.nvm/versions/node/v6.11.0
# copy the relevant files and directories to the node path
cp  -r /root/.nvm/versions/node/v6.11.0/{bin,lib,share} /usr/local/nvm

# next install iwatch 
apt-get update && apt-get install iwatch

# create a directory to house the iwatch config file and the command to be run when there are changes to the v6.11.0 node version
mkdir -p /root/.nvm_iwatch

cd /root/.nvm_iwatch
# set up callback script for iwatch
echo "
#! /usr/bin/env bash

rsync -a --include='bin/***' --include='lib/***' --include='share/***' /root/.nvm/versions/node/v6.11.0/ /usr/local/nvm --exclude='*' --delete

" > exec.sh

chmod a+x exec.sh

# set up config for iwatch to run in daemon mode
echo '<?xml version="1.0" ?>
<!DOCTYPE config SYSTEM "/etc/iwatch/iwatch.dtd" >

<config charset="utf-8">
  <guard email="iwatch@localhost" name="iWatch"/>
  <watchlist>
    <title>NVM Watch</title>
    <contactpoint email="root@localhost" name="Administrator"/>
    <path type="recursive" events="modify,close_write,create,delete,move,delete_self,move_self" exec="/root/.nvm_iwatch/exec.sh">/root/.nvm/versions/node/v6.11.0</path>
  </watchlist>
</config>
' > iwatch.xml

# now start iwatch in daemon mode

iwatch -d -f /root/.nvm_iwatch/iwatch.xml

# append this directory to path for all users
echo 'export PATH="$PATH:/usr/local/nvm/bin"' >> /etc/profile

# activate this profile
source /etc/profile

Brief Explanation

The script above installs a preferred version of node js ( can be any version) in this case v6.11.0 with nvm. It then copies this version to a more central location: /usr/local/nvm. Using iwatch and rsync, it watches the nvm version directory (/root/.nvm/versions/node/v6.11.0) for changes (as might occur when a new global package is installed for instance) and replays this changes in the /usr/local/nvm directory. Finally it adds this directory to the /etc/profile path so every user has access to binaries of node packages.

Note

Remember to change the node version number if installing multiple versions.

Wrap Up

That pretty much covers it. The Debian box should now have node js installed in a manner that is quite convenient