DEV Community

Cover image for How I Manage Node & Package Manager Versions
Michal Bryxí
Michal Bryxí

Posted on • Edited on

How I Manage Node & Package Manager Versions

The problem

On OSX, when it comes to managing version of things in NodeJS world, there are many options nvm, n, nodenv, volta, homebrew for NodeJS management and other heap for package manager versions.

This process in this article tries to achieve only those things:

  1. Things works seamlessly. I switch projects, correct (versions) of tools are automatically used.
  2. Minimal process to setup new projects is needed.
  3. Local development environment and CI both use the same ways to ensure consistency.

NodeJS version management

Homebrew

No. Although it's super fast, reliable and stable, you will very quickly run into many problems:

  • One project needs version A, while other needs version B.
  • Your local environment uses A, while CI uses B.
  • Switching versions is manual, slow and costly.

nvm, n, nodenv, ...

Maybe. I don't have anything against any of those projects. I just happened to land on the next one. Might work for you just ok.

volta

Yes. The nice thing about volta is that it's super fast to install, works reliably and lets you know when something is :sus:.

Package manager version management

Corepack

No. Corepack is natively present in Node since version 16.9.0, so more recent systems you won't have to do too much. But as per this blogpost on socket.dev and this pull request in node corepack is likely to be removed from node and additional steps will be necessary to install it.

volta

Yes. My package manager of choice pnpm is partially supported, so with a little bit of (temporary) configuration, this is a perfect solution. Also we have to use only one tool for managing node and package manager versions..

The solution

Prepare

You will need to do these steps only once.

If you want to follow along, first, you'd want to remove all the other tools you might have installed as there is high chance that they will interfere with your new stack:

brew uninstall pnpm # do not use brew to manage pnpm
brew uninstall node # do not use brew to manage node
brew uninstall nvm # do not use nvm/n/nodenv/...
corepack disable # do not use corepack
Enter fullscreen mode Exit fullscreen mode

Then we will install volta (I will copy&paste below, but better if you just follow the official guide):

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

volta install node
Enter fullscreen mode Exit fullscreen mode

Now to enable PNPM support in Volta you will need to add VOLTA_FEATURE_PNPM=1 to your environment variables. If you're using zsh like me, you might want to add it in following way:

# ~/.zshenv
export VOLTA_FEATURE_PNPM=1 # Your new line
export VOLTA_HOME="$HOME/.volta" # Already added by volta installation
export PATH="$VOLTA_HOME/bin:$PATH" #Already added by volta installation
Enter fullscreen mode Exit fullscreen mode

At this point most of the manuals will tell you to start a new shell. To prevent stepping on a rake, I would recommend doing a quick system reboot. I think it's worth the little wait.

Project modifications

Ton pin down the versions in your project use volta pin command in directory of your package.json:

volta pin node@18
volta pin pnpm@9.9.0
Enter fullscreen mode Exit fullscreen mode

GitLab CI

I battled a bit with GitLab CI to make this work nicely, but following should work for you:

# .gitlab-ci.yml
image: node:18

before_script:
  # There is an ugly catch-22 situation that GitLab CI
  # does not have a good way to modify all the needed
  # environment variables in the correct way
  # and at the right time, so this will have to do.
  - source .gitlab-ci-env.sh

stages:
  - build
  - test

cache:
  paths:
    # Make sure to persist our volta installation 
    # between individual stages.
    - .volta
install_dependencies:
  stage: build
  script:
    - apt-get update
    - apt-get install -y curl
    - curl https://get.volta.sh | bash
    - pnpm install

testing_testing:
  stage: test
  script:
    - pnpm test
Enter fullscreen mode Exit fullscreen mode

And then put this file next to .gitlab-ci.yml:

# .gitlab-ci-env.sh

# Enable support for PNPM
export VOLTA_FEATURE_PNPM=1

# We want volta to be installed into our project dir,
# otherwise GitLab won't be able to cache it.
export VOLTA_HOME="$CI_PROJECT_DIR/.volta"

# Adjust $PATH so we can call volta executable.
export PATH="$VOLTA_HOME/bin:$PATH"
Enter fullscreen mode Exit fullscreen mode

Conclusion

There are many ways to do version management. I think that this one is the simplest, while allowing the greatest level of flexibility. But happy to adjust the article (already did :)) if someone shows me a better way.

Top comments (0)