Switching to PNPM for Everything Node.js?

December 19, 2023

I have long used NVM to control my Node.js versioning locally and NPM to install Javascript packages. But recently, I have been really enjoying using PNPM for managing this blog. And I was wondering what features of PNPM I can use throughout my workflow. Can it really replace both NPM and NVM for me entirely?

In this blog post I talk about my exploration in switching to using PNPM everywhere instead of NPM and NVM. Use it as my default package manager. And more importantly, use it as my Node.js version manager. Of course nothing is easy, if you attempt to use PNPM to manager your Node.js version and you did not install it as an indepentent application you get this warning:

$ pnpm env install --global lts
 ERR_PNPM_CANNOT_MANAGE_NODE  Unable to manage Node.js because pnpm was not installed
using the standalone installation script

If you want to manage Node.js with pnpm, you need to remove any Node.js that was
installed by other tools, then install pnpm using one of the standalone scripts that
are provided on the installation page: https://pnpm.io/installation

Luckily this is easy to fix. First, we need to remove NVM. We might as well make sure we remove any installed Node.js versions too. Running the following commands did this for me:

$ rm -rf "$NVM_DIR"
$ fisher remove jorgebucaran/nvm.fish
fisher remove version 4.4.4
Removing jorgebucaran/nvm.fish
         /Users/josh/.config/fish/functions/_nvm_index_update.fish
         /Users/josh/.config/fish/functions/_nvm_list.fish
         /Users/josh/.config/fish/functions/_nvm_version_activate.fish
         /Users/josh/.config/fish/functions/_nvm_version_deactivate.fish
         /Users/josh/.config/fish/functions/nvm.fish
         /Users/josh/.config/fish/conf.d/nvm.fish
         /Users/josh/.config/fish/completions/nvm.fish
Removed 1 plugin/s
$ brew uninstall node

NOTE: I use the Fish shell. Read about that here! And these are the steps I needed to remove NVM. If you use Bash or Zsh you will need to remove the below lines from your rc file:

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[[ -r $NVM_DIR/bash_completion ]] && \. $NVM_DIR/bash_completion

Next we reinstall PNPM using their stand-alone script found here. Since I have curl installed, getting PNPM is done by this command:

$ curl -fsSL https://get.pnpm.io/install.sh | sh -

And finally, we can use PNPM to manage our Node.js versions!

$ pnpm env use --global lts
Fetching Node.js 20.10.0 ...
Node.js 20.10.0 was installed
  /Users/joshfinnie/Library/pnpm/nodejs/20.10.0
Node.js 20.10.0 was activated
/Users/joshfinnie/Library/pnpm/node -> /Users/joshfinnie/Library/pnpm/nodejs/20.10.0/bin/node

This is a powerful tool. Read more here to see all you can do.

One drawback with this setup is that you can only use PNPM to manage your Node.js version globally. Trying the pnpm env use commmand within a project with a specified Node.js version does not work. You get this error:

$ pnpm env use
 ERR_PNPM_NOT_IMPLEMENTED_YET  "pnpm env use <version>" can only be used with
the "--global" option currently

I do not think this is as much of a show stopper as it use to be. But I cannot wait until PNPM allows us Node.js versions per project. I am finding it useful to just run the latest LTS verion of Node.js everywhere anyways.

Hope you find this short blog post helpful. If you also swap to using only PNPM let me know! Find me on Threads and strike up a conversation.