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
If everything goes according to plan, you'll see the nice, rotating React logo when you open up a browser at http://localhost:3000
.
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.
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.
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!
When you've successfully added your Node version, you'll see the following success message in your terminal: pinned node@16.11.1 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.
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.
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.
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.
And if you’d like to make sure you never miss an article I write, sign up for my newsletter here: https://paigeniedringhaus.substack.com
Top comments (0)