I absolutely hate using version managers like nvm and rvm.

These days I don’t run any project session management like tmuxinator and tend to forget that I need to be switching Node.js versions depending on the project I am on.

I know, I know… I really should get back to automating my project sessions a bit more, that one’s on me. In a perfect world, every project I touch would be Dockerized and everything would be amazing, but that’s sadly not the world we live in.

Okay, so outside of my own “senior moments” with juggling versions, the bigger problem I always had with these version managers (again, speaking directly about both rvm and nvm) is that their initialization scripts that need to be sourced tend to slow down your shell prompt.

I’m not talking about a few extra milliseconds, I’m talking about a noticeable lag when starting up a new terminal.

Okay, so it’s like a ~1 second delay, pretty manageable for most people.

Not me though, I live in the terminal and use GNU Screen and am constantly opening up new tabs, windows and virtual consoles like it’s my job.

Okay, so it’s kind of my job ;)

Even on brand new hardware, I’ve noticed this delay. Fortunately, I got fed up with this a while back and set out to create a solution.

My thought was that most of the time I don’t need nvm available. The MVP of this was to just source the nvm initialization script only when I needed it.

I even created a nice script that I could run so I didn’t have to keep looking up what the command was.

That was the MVP and it worked somewhat well until I realized that I so rarely was using nvm that it became a chore to remember what the hell I named that command!

The next iteration was to create a shell alias that would replace nvm with some logic that would attempt to run the initialization script and THEN try to run the real nvm which the initialization script made available:

function nvm {
  if [ -z ${NVM_DIR+x} ]; then
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
    nvm "$@"
  fi
}

It works pretty great for the most part, the only exception being that if you use GNU Screen like I do and run nvm prior to starting a screen session, nvm won’t work inside any of your windows.

The bigger caveat there is that if you DON’T run nvm prior to starting your screen session, you will need to run nvm in each window that you create.

Really just means I need to be mindful about trying to juggle Node.js versions within a single screen session.

A bit more in the YMMV department, the aforementioned alias worked fantastic on Debian stable which nvm was installed to ~/.nvm/.

If you’ve installed to another directory you may need to make some adjustments to the path.

Also, Arch Linux’s AUR package for nvm comes with a helper script installed to /usr/share/nvm/init-nvm.sh which can be sourced instead:

function nvm {
  source /usr/share/nvm/init-nvm.sh
  nvm "$@"
}