How to use Volta and why you should consider it over nvm
Node.js is alive and well, they've released version 17 into the ecosystem on October 19th, 2021. Along with Node.js 17 brings npm 8 and many cool new features. Now as you go to try it out, it's also a good time to think about how you're managing your toolchain.
Working on projects, big or small, it is important that all contributors are using the same versions of tools like node
, npm
, yarn
, tsc
, etc. This helps us mitigate both technical risks and potential business risks associated with it.
Volta (previous name: Notion, also nemo originally too) is a fantastic tool created to solve your toolchain issues properly.
What makes Volta so great?
The best phrase I can think of to explain Volta is magic. Yep, it's magic. It will magically (well, using a shim that proxies you to the right thing) get the right tool for you.
Now, I'm not just talking about node
here, I'm talking about things like npm
and tsc
as well. Volta is so great that it can ensure everyone in your project uses the right typescript binaries from command line, instead of their potentially whack global version.
Although Volta still supports global versions, and requires you to do that first. But Volta will automagically switch to your project's configured version if it's specified.
Let's start with a basic example. Jumping into a test project, let's assume in production it was running on node v15 and npm v7. Let's pin that to the project!
➜ my-project $ volta pin node@15
success: pinned node@15.14.0 in package.json
➜ my-project $ volta pin npm@7
success: pinned npm@7.24.2 in package.json
So wait, what just happened? You just configured your project with node 15 and npm 7. Nothing feels dramatic here, it's an effortless feeling, all that we see is these few lines that have popped into the package.json
file, lets grep for volta
here:
➜ my-project $ grep -A3 volta package.json
"volta": {
"node": "15.14.0",
"npm": "7.24.2"
}
Neat, I guess! So did it work?
➜ my-project $ node --version
v15.14.0
➜ my-project $ npm --version
7.24.2
It sure did! So now, whenever your terminal changes to this directory (or any of its subdirectories), Volta will (like magic) know to use that version. But hang on, what happens if we don't have the version installed? Let me change my node version in the volta
object to 15.13.0
and show you what happens.
As you can see, Volta detected that we don't have that version installed and did it for us (again, magic!).
Lets move into the next example which is related to typescript. Using Volta we can install global tools as well, this way the binaries in that package become apart of our shell.
➜ my-project $ volta install typescript
success: installed typescript@4.5.2 with executables: tsc, tsserver
Take note here that typescript has been installed globally at version 4.5.2 and notes the executables tsc
and tsserver
. That really isn't interesting, npm can do that for us already - but we did this so tsc
would be checked for in our path. I want it to use the version in my package. So lets add the beta version as a dev dependency for the sake of this demo:
➜ my-project $ npm i --save-dev typescript@beta
changed 1 package, and audited 2 packages in 4s
found 0 vulnerabilities
➜ my-project $ tsc --version
Version 4.5.0-beta
Notice how its not using the global version, but the version installed in my node_modules/.bin
directory? Now everyone is on the same toolchain. Awesome!
Now you know how easy it is to set your version of node, tsc, and everything else in your path, plus ensure everyone else working on the project is on the same version. Let's go ahead and upgrade node and npm, it's simple: pin, and then commit your new package.json file!
Hows this for thought - you could also consider using Volta in your Docker images, so that way even production matches up perfectly.
Diving deeper: whats really going on?
This is a bit more technical.
Volta does not use anything crazy. It uses a simple but verified method of shims. Whatever tool you install using Volta, it adds a shim to your PATH
which acts as a router to the correct version, and don't worry it is fast.
So to elaborate, once you install a global version of say, tsc
from the typescript package (you would have usually done this through yarn global add typescript
) it will add it to your path.
Volta is keeping record of this in the ~/.volta/tools/user/bins/
directory, but dumps them into your path by create an alias to volta-shim
in ~/.volta/bin/
➜ ~ $ ls -al ~/.volta/bin/node
~/.volta/bin/node -> ~/.volta/bin/volta-shim
When you run a shim, it will check for a package.json file (working back through your file path if it needs to) and find that volta
key value set of versions to ensure it loads the correct version, if it can't find one it'll use the global default.
It creates a cache of these tools in the ~/.volta/tools/image/
directory so if it's not downloaded on your system, it grabs it for you.
This lets you trust your globally installed packages. You can read more about "Global installs done right" on their own blog where they go into a good example with Mocha.
Why is this better than nvm?
For starters, nvm is only supported on Unix environments. Although that is my preference, I also believe in supporting the preference of other developers. Sure, there is nvm-windows, but they act slightly different - wouldn't it be nice to have one solution that ensures everyone gets the same result to matter their operating system preference?
Another downfall to using nvm in is that you need to either use command line helpers, or manually type a command. It also doesn't handle things like npm
and yarn
versioning very well, and it doesn't do other things for your toolchain like seed your node_modules .bin directory (important when working with typescript projects - see above!)
Another nice perk is that Volta is created in rust (check it out on GitHub), which compiles down to a really slim and fast binary, whereas nvm is a node project which is why it is not as fast.
Let's install Volta!
Are you in love?
For those that have access to a Unix shell, you can get started like this:
curl https://get.volta.sh | bash
For windows users, go ahead and download the installer on their website.
Thats it. Restart your command line tool, and enjoy! You can thank me later.
Appreciate you taking the time to read my blog. Feel free to subscribe, and I'll try my best to keep this blog updated.