There is nothing more annoying than updating Node, feeling good about it, and then watching your terminal spit out nvm: command not found the second you reopen a tab. Getting your runtime sorted out cleanly comes down to two main things: hooking up your shell config properly so your path stays intact, and pulling your global CLI tools along for the ride so your daily workflow doesn’t suddenly break.
- Recommended LTS Version: Node.js 20.x LTS or newer
- Best Overall Approach: NVM (Node Version Manager)
- Carry Over Global Packages:
--reinstall-packages-from=default - Quick Version Check:
node -v
Should You Choose LTS or Current?
For everyday development and anything touching production, stick with the LTS (Long Term Support) release every single time. The Node team supports these builds with security patches and critical bug fixes for three full years. That long shelf life is what keeps your packages, build tools, and frameworks humming along without throwing surprise deprecation warnings in the middle of a sprint.
The Current branch is really just a playground for whatever the team is building right now, including bleeding-edge JavaScript features and experimental APIs. You only want to grab Current if you are actively testing out a brand-new package or feature that explicitly calls for it. Otherwise, sticking to LTS is the easiest way to keep your build pipelines from falling apart out of nowhere.
Step 1: Check Your Current Node and NPM Versions
Before touching any configurations or pulling down installers, take five seconds to see what you actually have installed right now. Just pop open your usual terminal window or command prompt.
Check which Node binary you are running: node -v
Then see which version of NPM is attached to it: npm -v
Jot down or keep an eye on both numbers. Having that baseline makes it super easy to confirm that your update actually took hold in a couple of steps.
Method 1: The Safest Way to Update Node.js (Using NVM)
If you ask pretty much any seasoned dev, they will tell you Node Version Manager is the way to go. It lets you stash multiple runtime versions side by side and flip between them whenever you want without breaking a sweat. Even better, it runs entirely in user-space, so you completely dodge those awful root permission headaches that standard installers love to create.
Updating via nvm-windows
Because the original NVM project relies on shell scripting, Windows needs its own standalone tool called nvm-windows. You can grab the setup file straight from its official GitHub releases page. Just remember to launch PowerShell as an Administrator before running these commands so Windows doesn't block the file symlinks.
Take a look at what versions are ready to download: nvm list available
Pick out the freshest LTS release number and pull it down: nvm install 20.11.0
Switch your environment over to start using it: nvm use 20.11.0
Updating via NVM for macOS and Linux
On a Mac or Linux box, NVM hooks straight into your native shell environment, which makes managing versions feel a lot more seamless. You just pull down the target version directly from the remote registry.
Grab the latest stable LTS build: nvm install --lts
Make sure your shell defaults to this release every time you spin up a fresh session: nvm alias default 'lts/*'
How to Migrate Global Packages to the New Version
A lot of folks hold off on updating Node because they dread reinstalling all their favorite global CLI tools like TypeScript, ESLint, or Nodemon. Luckily, NVM has a handy built-in trick that copies all those global modules straight into the new environment while it installs.
Run this to install your new version and pull your current global setup right along with it: nvm install 20.11.0 --reinstall-packages-from=default
That single flag does all the heavy lifting and saves you from tracking down every random utility you forgot you had installed globally.
Fixing nvm: command not found After Restart
Modern macOS builds run Zsh out of the box, while most Linux distros and older setups stick with Bash. If NVM works fine until you close your terminal window and then completely vanishes, it just means your shell isn't loading the startup script when it boots up.
To fix that permanently, you just need to drop the NVM initialization snippet into your ~/.zshrc or ~/.bashrc. Open that file in your text editor and add these two lines down at the very end:
export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Save changes, run source ~/.zshrc to refresh your active session, and you are good to go. The nvm command will stick around reliably across every new window you open.
Project-Specific Versions with .nvmrc
When you are juggling multiple legacy repos, you can't always drag every project onto the shiny new Node version right away. The clean way to handle this is dropping a tiny .nvmrc file right into the root of each project folder.
All that file needs inside is the version string, something like 18.17.0. The next time you cd into that directory, just type nvm use and your environment will automatically pivot to whatever version that codebase expects.
Method 2: Updating Node.js Using the n Package (macOS/Linux)
If you are on Unix and want something even lighter than NVM, the n package is a solid community favorite. It is literally just an NPM package designed to handle version switching without adding a bunch of shell helper functions. Keep in mind, this one won't work on Windows at all.
Start by installing the utility globally through your current NPM setup: npm install -g n
Then tell it to grab and wire up the current LTS build: sudo n stable
Because n drops files into system-level directories like /usr/local, you do need that sudo prefix here to give it the write access it needs.
Method 3: Updating via Package Managers (Homebrew, Winget, Chocolatey)
Using an OS-level package manager is pretty tempting because it bundles your Node updates right alongside the rest of your daily software.
If you are on a Mac running Homebrew, you just run: brew upgrade node
If you are on a modern Windows setup, winget is the cleanest native route these days: winget upgrade OpenJS.NodeJS
These commands get the job done quickly, but you lose almost all the flexibility that version managers give you. They overwrite your current installation in place, meaning if an update suddenly breaks your project, rolling back to your old setup is a massive chore.
Method 4: Using the Official Node.js Installer
Heading over to the official Node.js website and downloading an MSI or PKG installer is how most of us started out. You grab the file, run the wizard, click "Next" a few times, and let it overwrite the binary on disk.
The downside is that this approach is pretty rigid. It drops Node into system-wide folders, which almost always comes back to bite you down the road with annoying permission errors whenever you try installing global packages.
Do You Need to Uninstall the Old Version First?
If you are managing your setup with NVM or n, you don't need to wipe anything beforehand. Those tools are built to keep isolated versions tucked away alongside each other peacefully.
That said, if you are moving across several major versions on Windows using the traditional MSI installer, going through Add/Remove Programs to clear out the old version first is usually a smart move. It saves you from dealing with stale registry entries or lingering environment variable paths.
How to Update NPM Separately
While Node ships with a bundled version of NPM out of the box, the NPM team pushes updates on their own schedule much more frequently. You can easily bump NPM up to its latest build without touching your underlying Node runtime at all.
Tell NPM to pull down its own latest stable release globally: npm install -g npm@latest
Close and reopen your terminal, run npm -v, and you should see the fresh version reflected right away.
Troubleshooting Common Node.js Update Errors
Whenever you change core development runtimes, leftover environment paths or stale cache files can cause weird glitches. A few straightforward checks can usually tell you what went sideways.
Diagnosing PATH Conflicts (Using which node)
A classic head-scratcher is installing a new version successfully, only for node -v to stubbornly spit out your old version number. That almost always means you have two different Node installations on your drive competing for priority in your system PATH.
Find out which binary your terminal is actually picking up first: which node
If the output points somewhere like /opt/homebrew instead of your .nvm folder, open your shell profile and make sure your NVM block sits at the very bottom of the file so it wins the PATH priority. This kind of PATH confusion happens all the time on machines that juggle multiple runtimes, like when upgrading pip in Python right alongside a Node environment.
EACCES Permission Denied Errors
You will usually run into nasty EACCES permission denied errors when NPM tries writing files into a directory that belongs to the root user. This is the classic symptom of setting up Node with a direct website installer instead of a user-level version manager. If you ever need to sort out environment variables on Windows to unstick a broken PATH, checking a dedicated setup guide makes sorting out GUI settings versus PowerShell quick work.
The clean fix here is resetting the ownership of your hidden .npm directory back to your actual user account. Whatever you do, resist the urge to run sudo npm install -g, since that just creates a security mess and makes your permission issues worse later on.
Corrupted NPM Cache (npm cache clean)
If your package installs start hanging indefinitely or throwing cryptic integrity check errors right after you update Node, a stale or busted local cache is usually the culprit.
You can wipe that temporary staging area clean in one shot: npm cache clean --force
That flushes out the stale cached packages and forces your package manager to fetch pristine copies from the registry on your next install run.
If you happen to use AWS CDK, keep an eye out for library version mismatches right after a Node runtime bump - taking a look at how to update AWS CDK will get your deployment stacks back in sync quickly.