Installing Node.js with NVM

Using NVM to juggle Node.js versions

These days in web applications, Node.js platform is ubiquitous.

For frontend tooling, the npm (node package manager) part of Node.js tool set will likely be part of that your frontend tool set.

For backend services, to say that Node.js is extremely popular would be an understatement. There are many reasons, including the ability to transfer JavaScript platform knowledge around frontend programming to backend programming, and the platform itself:

Node.js is primarily used for non-blocking, event-driven servers, due to its single-threaded nature. It’s used for traditional web sites and back-end API services, but was designed with real-time, push-based architectures in mind. — Tomislav Capan

The Problem

There’s one slight problem, the Node.js platform and community of tools and libraries are fast moving targets, and what might work under one Node.js version will not be guaranteed to work for another version of Node.js. For this reason, you need a way to not only install Node.js easily, but also switch between Node.js versions.

This guide demonstrates how to do install and use NVM (Node Version Manager) to accomplish this on Linux, macOS, and Windows.

Installing NVM

Linux

We can get the latest stable version of NVM using this process:

export NVM_DIR="$HOME/.nvm" && (
git clone https://github.com/creationix/nvm.git "$NVM_DIR"
cd "$NVM_DIR"
git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"

In your startup script, e.g. ~/.bashrc, ~/.profile, ~/.zshrc, you’ll need to add this:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

Once this is setup, you can install Node:

# chose desired node version
VERSION
="8.12.0"
# install node
nvm install ${VERSION}
nvm use ${VERSION}

macOS

You can easily install NVM using Hombrew.

# chose desired node version
VERSION
="8.12.0"
# install nvm
brew install nvm
source $(brew --prefix nvm)/nvm.sh
echo 'source $(brew --prefix nvm)/nvm.sh' >> ~/.profile
# install node
nvm install ${VERSION}
nvm use ${VERSION}

Windows

NVM is actually not supported on Windows, but there’s a similar on Windows called NVM-Windows. With Chocolatey package manager solution installed, we install this with compiler support, and a spiffy console by running this in PowerShell:

# chose desired node version
$version = "8.12.0"
# install nvm w/ cmder
choco install cmder
choco install nvm
refreshenv
# install node
nvm install $version
nvm use $version

Basic Usage of Node.js

Versions at User Level

Once NVM is installed and available, you can easily switch between Node.js for your current user, by running this:

# install multiple node version
nvm install 10.13.0
nvm install 11.2.0
# choose current node version
nvm use 10.13.0

Versions at Project Level

If you would like your a different version of Node.js per project level, you can create a .nvmrc file that contains the desired version.

mkdir new_project && cd new_project
echo '8.12.0' > .nvmrc
nvm use

Advanced: Build Requirements

Many node packages require compilers and python 2 to be installed on your system. This is because they require use of the tool node-gyp.

I wrote a previous blog on how to get compilers for Linux, macOS, and Windows:

These days, there’s a big push to embrace and use Python 3. You can use both Python 2 and Python 3 on the same system easily, which exception of Windows, due to how Windows uses file associations for launching files. One way to juggle different Python environments is to use a tool like pyenv.

I wrote a blog on pyenv for Linux and macOS with an alternative for Windows:

Validating Node.js Platform

We can install some packages to test out if your system is working. Many node packages use node-gyp build tool, a cross platform tool written in Node.js for compiling addon modules. With compilers and python 2 installed, you can try out packages that require this tool.

One popular package that uses node-gyp is the bcrypt package. If you can get this installed, then you have a system that will work for most Node.js packages.

npm install -g bcrypt

Popular Packages

This is just a few of the packages or solutions I have used professionally. You can optionally install these:

# build-task automation tools
npm install -g grunt
npm install -g gulp
npm install -g webpack
# web microframework 
npm install express
# database ORM
npm install sequelize
# languages
npm install -g coffeescript
npm install -g typescript
# frontend framework
npm install -g @angular/cli

Example Server

I created a simple hello world web service using the Express web micro-framework, similar to the famous Sinatra, but for Node.js. You can use this to test out your environment.

mkdir -p hellojs && cd hellojs
cat <<-'PKG_MANIFEST' > package.json
{
"name": "express_hello_world",
"version": "1.0.1",
"description": "Express Hello World",
"author": "Joaquin Menchaca",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.13.3"
}
}
PKG_MANIFEST
cat <<-'SRVR_CODE' > server.js
'use strict';

const express = require('express');

// Constants
const PORT = process.env.EXPRESS_PORT || "8080";

// Application
const app = express();

// Multiple Route Scenario
app.get(['/', '/hello'], function (req, res) {
res.send('Hello world!\n');
});

// Dynamic Route Scenario
app.get('/hello/:username', function(req , res){
res.send("Why, Hello " + req.params.username + '!\n');
});

app.listen(PORT);
console.log('Running on http://localhost:' + PORT);
SRVR_CODE
npm install
npm start
curl -i localhost:8080
curl -i localhost:8080/Cindy
curl -i localhost:8080/Rachael

The source code above is from:

Conclusion

I use NodeJS for my own projects and frequently come across this professionally, both for backend services and frontend code.

In DevOps cultures and build-release engineering roles, I have tooled in continuous integration support with Docker for backend services, and explored using GCS (Google Cloud Storage) buckets with Fastly CDN. In one recent organization, they used WebPack, Gulp, and Grunt for doing asset pipeline tasks, where JavaScript is run through templates, compressed, obfuscated, or otherwise packaged before making it available.

I mostly bounce between macOS (development platform) and Linux (target production environment). At times, some developers need Windows support, especially for testing Windows-only browsers.

Whatever your platform, I hope this is useful.