A Node Patch Upgrade Should Not Make Your Global Tools Disappear

You upgrade Node through nvm, switch to the newest patch, and discover that the global CLI you used five minutes ago is gone.
Nothing is technically broken. Each Node installation has its own global package directory. Your packages are still sitting under the previous patch version, perfectly safe and perfectly useless to the shell you just opened.
It is the package-manager version of moving apartments and leaving the knives in the old kitchen.
node-snapshot is the small CLI I built to make those global tools explicit.
Track an LTS line, not one disposable patch
Install the tool from my Homebrew tap:
brew install AndrewDongminYoo/tap/node-snapshot
Its configuration names the nvm LTS aliases you want to track. A snapshot stores the resolved Node version and global package list for each alias in a separate JSON lock file.
node-snapshot snapshot
node-snapshot status
The important distinction is that the alias is stable while its concrete installation changes.
lts/jod can move to a newer patch; the lock remains the record of what should travel with it.
Upgrade and carry the tools forward
The direct path is:
node-snapshot upgrade
When an LTS version changes, the command asks nvm to reinstall packages from the old version into the new one. It then refreshes the snapshot.
You can also check without installing:
node-snapshot upgrade --check
This is intentionally not a replacement for nvm. It is the layer that remembers the user-installed tools nvm keeps isolated by version.
Recover packages scattered across old patches
Sometimes the tidy upgrade path is already behind you. Several patch directories exist, each with a slightly different set of global packages, and the newest installation is the emptiest one.
That is what consolidate is for:
node-snapshot consolidate jod
It scans the installed patch versions in that major line, takes the union of their user-installed packages, and installs anything missing into the current LTS version. Scoped packages are handled as packages rather than mistaken for directories.
After it refreshes the snapshot, consolidate attempts to uninstall each older patch installation in that tracked major line.
Check the command output before assuming only the latest remains.
Do not run it when those older installations must remain available.
There is also an explicit migration command when you want to copy the recorded set between LTS aliases:
node-snapshot migrate iron jod
The empty snapshot is the dangerous one
The nastiest timing window appears immediately after a new Node version is installed.
The active version is new, so its global set may be empty.
A naive snapshot would faithfully replace a populated lock with {}.
Very accurate. Very destructive. Excellent teamwork, everyone.
node-snapshot refuses that full wipe by default.
If the live set is empty while the lock still records packages, it stops and tells you how to restore or how to override the guard deliberately.
That refusal is the feature I care about most. Backup tools should not silently memorialize an accident.
Make directory changes useful again
The optional zsh integration switches Node when you enter a directory containing .nvmrc or .node-version, prints the active toolchain, and checks for upgrades in the background:
source <(node-snapshot init)
The project is deliberately narrow: nvm, zsh integration, LTS aliases, and global npm packages. It does not try to become a universal version manager.
If your global CLIs keep vanishing between Node patches, install node-snapshot.
Your tools can move with the runtime instead of becoming archaeological evidence under ~/.nvm.
Get the next post.
If you made it to the end, meet the next post in your inbox or RSS reader.