First published October 18, 2021 in newline

Introducing Volta - it manages your Node.js versions so you don't have to

With Volta, the old saying of "It works on my machine..." will become a thing of the past.

Lightning bolt

Photo by Felix Mittermeier on Unsplash

Web development's not easy

When you're working with a team of developers, especially on a team responsible for managing multiple applications, you very well might have JavaScript apps that run on different versions of Node.js.

Some might use Node 10, others Node 12, some may use Yarn as their package manager, others might use npm - and keeping track of all that is really hard. Ensuring every developer on the team is developing with the correct versions all the time is even harder. But it's essential.

While the consequences might be relatively minor during local development: it works on one dev's machine and throws an error on another's, this sort of lack of standardization and clarity can have devastating effects when it comes to production.

I speak from personal experience when I say this sort of thing happened to me and my development team.

We built our app on local machines running Node 10, but the build pipeline defaulted to the lowest Node version it had on hand, Node 6, and the app wouldn't start up in production. We had to roll back the deployment, figure out what went wrong - it turned into a very long night. It went on to live in infamy as "Dark Thursday" for all who experienced it.

And it could have all been avoided if we'd been using a handy little tool called Volta. I want to introduce Volta to you today so you can avoid the stress we went through - it's simple to get started with and can prevent catastrophes like this.

What is Volta?

Volta touts itself as "a hassle-free way to manage your JavaScript command-line tools."

What this means in practice is that Volta makes managing Node, npm, yarn, or other JavaScript executables shipped as part of packages, really easy.

Why Volta?

I've told you what Volta is, but you're probably still wondering why I chose it in particular - it's certainly not the only game in town. NVM's another well known option for managing multiple versions of Node.

NVM 

I used to use Node Version Manager (NVM) myself. Heck, I even wrote a whole blog post about how useful it was.

NVM is good, it does exactly what it sounds like: it allows you to easily download and switch versions of Node.js on your local machine.

While it does make this task simpler, NVM is not the easiest to setup initially, and, more importantly, the developer using it still has to remember themselves to switch to the correct version of Node for the project they're working on.

Volta

Volta, on the other hand, is easy to install and it takes the thinking part out of the equation: once Volta's set up in a project and installed on a local machine, it will automatically switch to the proper versions of Node.

Yes, you heard that right. Similar to package managers, Volta keeps track of which project (if any) you’re working on based on your current directory. The tools in your Volta toolchain automatically detect when you’re in a project that’s using a particular version of the tools and takes care of routing to the right version of the tools for you.

From that point on, every time you run Node inside your project directory, Volta automatically switches to that same version of Node you chose.

Not only that, but it will also let you define yarn and npm versions in a project, and if the version of Node defined in a project isn't downloaded locally, Volta will go out and download the appropriate version.

But when you switch to another project, Volta will defer to any presets in that project or revert back to the default environment variables. Cool, right?

Ready to see it in action?

Setup Volta in a project

For ease of getting started, let's create a brand new React application with Create React App, then we'll add Volta our local machine and our new project.

If you'd like to download a working version of this code, I have a GitHub repo here.

Spin up a new React app

First things first, create a new app.

Run the following command from a terminal.

$ npx create-react-app volta-sample-app

Once you've got your new React app created, open up the code in an IDE, and start it up via the command line.

$ npm run start

Starting sample React app locally

If everything goes according to plan, you'll see the nice, rotating React logo when you open up a browser at http://localhost:3000.

React app running locally

Now that we've got an app, let's add Volta to it.

Download Volta locally

Installing Volta to your development machine is a piece of cake - no matter your chosen operating system.

Unix

If you're using a Unix based system (MacOS, Linux or the Windows Subsystem for Linux  - WSL) to install Volta, it's super easy.

In a terminal, run the following command:

$ curl https://get.volta.sh | bash

Windows

If you've got Windows, it's almost this easy. Download and run the Windows installer and follow the instructions.

Once Volta's finished downloading, double check it installed successfully by running this command in your terminal:

$ volta -v

Hopefully, you'll see a version for Volta like my screenshot below. If you don't try quitting your terminal completely, re-opening a new terminal session and running that command again.

Current version of Volta The current version of Volta on my machine is now v1.0.5.

Define your environment variables

Before we add our Volta-specific Node and npm versions to our project, let's see what the default environment variables are.

Get a baseline reading

In a terminal at the root of your project, run the following line:

$ node -v && npm -v

For me, my default versions of Node and npm are v14.18.1 and v6.14.15, respectively.

Default versions of Node and npm on local machine

With our baseline established, we can switch up our versions just for this project with Volta's help.

Pin a node version

We'll start with Node. Since v16 is the current version of Node, let's add that to our project.

Inside of our project at the root level where our package.json file lives, run the following command.

$ volta pin node@16

Using volta pin [JS_TOOL]@[VERSION] will put this particular JavaScript tool at our specified version into our app's package.json. After committing this to our repo with git, any future devs using Volta to manage dependencies will be able to read this out of the repo and use the exact same version.

With Volta we can be as specific or generic as want defining versions, and Volta will fill in any gaps. I specified the major Node version I wanted (16) and then Volta filled in the minor and patch versions for me. Pretty nice!

Newly pinned Node version via Volta

When you've successfully added your Node version, you'll see the following success message in your terminal: pinned [email protected] in package.json (or whatever version you pinned).

Tip: Make your pinned Node version match your build server's Node version

Had Volta been an option at the time, my team might never have had to go through "Dark Thursday".

Instead, we could have pinned the same Node version used in our build pipeline and production servers to our project for local development to prevent such compatibility issues.

At the very least, we could have realized ahead of time we might have a problem with production before deploying.

Pin an npm version

That was pretty straightforward, now let's tackle our npm version. Still in the root of our project in the terminal, run this command:

$ volta pin npm

In this particular instance, I didn't even specify any sort of version for npm, so Volta defaults to choosing the latest LTS release to add to our project. Convenient.

Newly pinned npm version via Volta

The current LTS version for npm is 8, so now our project's been given npm v8.1.0 as its default version.

Check your package.json

To confirm the new JavaScript environment versions are part of our project, check the app's package.json file.

Scroll down to the bottom and you should see a new property named "volta". Inside of the "volta" property should be a "node": "16.11.1" and an "npm": "8.1.0" version.

Newly updated package.json with Volta Node and npm versions

From now on, any dev who has Volta installed on their machine and pulls down this repo will have their settings for these tools automatically switch to use these particular node and npm versions.

To make doubly sure, you can also re-run the first command we did before pinning our versions with Volta to see what our current development environment is now set to.

$ node -v && npm -v

After this, your terminal should tell you it's using those same versions: Node.js v16 and npm v8.

Watch the magic happen

Now, you can sit back and let Volta handle things for you. Just like that. 😎

If you want to see what happens when there's nothing specified for Volta (like when you're just navigating between repos or using your terminal for shell scripts), try navigating up a level from your project's root and checking your Node and npm versions again.

In the screenshot below, I opened two terminals side by side: the one of the left is inside of my project with Volta versions, the one on the right is a level higher in my folder structure.

I ran the following command in both:

$ node -v && npm -v

And in my project, Node v16 and npm v8 are running, but outside of the project, Node v14 and npm v6 are present. I did nothing but switch directories and Volta took care of the rest.

Volta using preset`s when specified and not when not specified

Try and tell me this isn't cool and useful. I dare you. 😉

Conclusion

Building solid, stable apps is tough enough without having to also keep track of which versions of Node, yarn and npm each app runs best with. By using a tool like Volta, we can take the guesswork out of our JavaScript environment variables, and actually make it harder for a member of the dev team to use the wrong versions than the right ones.

And remember to double check your local Node version matches your production server's Node version, too.

If you enjoyed this, you may be interested in checking out my course "The newline Guide to Modernizing an Enterprise React App".

In 10 modules and 54 lessons, I cover all the things I learned while at The Home Depot, that go into building and maintaining large, mission-critical React applications - because it's so much more than just making the code work.

From tooling and refactoring, to testing and design system libraries, there's a ton of material and hands-on practice here to prepare any React developer to build software that lives up to today's high standards. I hope you'll check it out.

Further References and Resources

Want to be notified first when I publish new content? Subscribe to my newsletter.