Getting Visual Studio Code and NVM Working Together

Patrick Smith
The Tech Bench
Published in
5 min readJul 17, 2016

I recently have worked on projects, some using Node.js 7, and others requiring the older version of 4. (It was released in September 2015. So old…)

So, I installed NVM, the Node Version Manager, and it worked a treat. I could now switch between version 4 and 7 at will. (I use the fish shell, so had to install some extras to get it working with that)

Using .nvmrc files within a project, nvm can automatically pick up which Node.js version you need. So myself, I just create the file and stick “4” or “7” in it depending on the project, and all my node … and npm … shell commands will use that specified version.

Using .nvmrc

Add a .nvmrc file to the project, containing in plain text the version of node you wish – use “7” for the latest version of Node.js, which brings most ES6 features (removing the need for transpiling with babel 🎉).

If this is a new version to your machine, then also install that version using “nvm install 7”.

Integrating with Visual Studio Code

However, there’s an issue with Microsoft’s fantastic Code editor. Code has amazing Node.js support, allowing the running and debugging of your node process, so has become my preferred editor. But I couldn’t get it to use the correctly version of node by using nvm and .nvmrc files.

I tried a number of approaches, but the one that worked for me was a combination of npm and editing Code’s configuration files.

Once you have a .npmrc file (see above for instructions), edit your project’s package.json file, and in the scripts section add a task for nvm:

macOS:

"nvm": "~/.nvm/nvm-exec which node | xargs -J % ln -sf % ./.nvm-node && chmod +x ./.nvm-node"

Linux (thanks Francesco & Denys):

"nvm": "~/.nvm/nvm-exec which node | xargs -I % ln -sf % ./.nvm-node && chmod +x ./.nvm-node"

Afterwards with the addition, my scripts section looks like:

(Rest of package.json)

"scripts": {
"start": "node index.js",
"nvm": "~/.nvm/nvm-exec which node | xargs -J % ln -sf % ./.nvm-node && chmod +x ./.nvm-node"
},

So what does this task do? By default, nvm installs files in your home directory, including the nvm-exec tool which picks up .nvmrc files. So I use it to ask for the path of node with the version we want, and then create a symbol link (with executable flag enabled) within the root of the project pointing to that specific node executable.

If you use git, I recommend adding .nvm-node to your project’s .gitignore file, as this symbolic link is specific to only your machine.

Debug is the 4th item in the sidebar with the bug icon

Then in project open in Code (open the project’s root directory), go to the Debug section.

You’ll find it in Code’s sidebar: the 4th item with the bug icon.

This is where you launch and use the built-in debugger.

Then click the ⚙ cog icon to open up Code’s launch settings. It will then ask which environment you have: select Node.js.

This will create and open a .vscode/launch.json file, if one is not already present.

In configurations, you will see a “Launch” task. We’ll be editing this.

  1. Change preLaunchTask to “nvm”
  2. Change runtimeExecutable to “${workspaceRoot}/.nvm-node”

This is what my file looks like after with the changes:

{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/index.js",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}",
"preLaunchTask": "nvm",
"runtimeExecutable": "${workspaceRoot}/.nvm-node",
"runtimeArgs": [
"--nolazy"
],
"env": {
"NODE_ENV": "development"
},
"externalConsole": false,
"sourceMaps": false,
"outDir": null
},

So the reason for jumping through hoops using npm is Code requires the runtimeExecutable value to be an absolute path, either to your disk or to your project. So by creating a symlink in our project to the correct version of node, we can get Code to cooperate.

It the UI that appears, choose npm. (Even if you use Gulp or Grunt I recommend npm, as npm can easily have tasks for running other tools, for example a build task that simply calls gulp)

Next we need Code to recognise our nvm task from npm. Open the Command Palette with the key combination ⇧⌘P on Mac / Control-Shift-P on Windows/Linux, then type “tasks runner” and open “Tasks: Configure Task Runner”.

This will open a .vscode/tasks.json file, created alongside the launch.json file we edited earlier. Add a new task for nvm at the top:

{
"taskName": "nvm",
"args": ["run", "nvm"]
}

This simply calls npm run nvm, running the nvm task we defined earlier in package.json.

My tasks.json file after the edits looks like this:

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "npm",
"isShellCommand": true,
"showOutput": "always",
"suppressTaskName": true,
"tasks": [
{
"taskName": "nvm",
"args": ["run", "nvm"]
},
{
"taskName": "install",
"args": ["install"]
},
{
"taskName": "update",
"args": ["update"]
},
{
"taskName": "test",
"args": ["run", "test"]
}
]
}

Now for the big moment.

Press the green play button ▶️ in Debug, and Node.js should launch, using the version of node specified in your .nvmrc file.

🎆 🍰 🎇

--

--

Patrick Smith
The Tech Bench

@concreteniche · Product designer for the web & Mac. Loves experimenting with React, Swift, and UX tools.