Published on Sep 29 2025
Last updated on Sep 29 2025
A common source of frustration in programming isn’t bugs in your code, but your computer not doing what you think it should. One example is Node.js. You install Node, check the version, and get a different one than expected. Sometimes node
and npm
don’t even agree.
This is not really a Node problem. It’s a PATH problem.
PATH is an environment variable. It’s just a string: a list of directories separated by colons. When you type a command like node
, your shell doesn’t know what “node” means. It searches those directories listed in PATH, left to right, until it finds an executable with that name. The first match wins.
You can see PATH by typing:
bash
1echo $PATH
It might look like this:
swift
1/Users/me/.bun/bin:/Users/me/.nvm/versions/node/v18.17.0/bin:/usr/local/bin:/usr/bin:...
That order matters. In this example, if node
exists in .bun/bin
, you’ll get Bun’s shim, even if you also have Node installed through NVM or Homebrew.
PATH is just a prioritized list of directories. But because most developers don’t think about it, PATH problems feel random. Two shells can give different results because the way PATH is initialized differs between them.
Most languages have one canonical way to install them. Node doesn’t. Node is unusual because it has multiple competing installation methods. Over the years, several approaches have developed in parallel:
System packages. Node can be installed by Homebrew (brew install node
on macOS) or apt (on Linux). These install into directories like /usr/local/bin
.
Version managers like NVM or Volta. These install under your home directory and adjust PATH dynamically.
Alternative runtimes. Bun and Deno ship their own binaries and sometimes replace node
directly.
Official installer. Node.js also provides a standalone installer that writes into /usr/local/bin
.
Each method works fine by itself. The trouble starts when you use more than one. They all want to “own” the node
command. PATH decides the winner.
The right way to debug this is not to uninstall everything in frustration. If node
or npm
don’t look right, the first thing to do is ask the shell which binary it’s running.
bash
1which node2which npm
This tells you the exact path of the executable. If they point to different directories, you’ve found the source of the mismatch.
Often one is coming from NVM and the other from Homebrew. That mismatch is what produces errors about version incompatibility.
Once you’ve seen what’s happening, you have to decide which system you want to use. You can’t use three at once. It’s not just untidy; it’s unworkable. If you don’t control which one is in PATH, you won’t be able to predict or reproduce behavior.
Often, NVM is the right choice. It doesn’t require sudo, keeps Node versions in user space, and lets you switch easily between projects. It’s also what most tutorials and collaborators expect.
If you choose NVM, the fix is simple:
Uninstall Node from Homebrew: brew uninstall node
Remove any official installer remnants in /usr/local/bin
.
Make sure your shell config (.zshrc
, .bashrc
) runs NVM’s initialization early, before other PATH modifications.
Demote or remove Bun from PATH if you don’t want it to shadow node
. (In simpler words, if you use Bun, move it later in PATH so it doesn’t override node
.)
Then restart your shell and verify:
bash
1which node2which npm3node -v4npm -v
If both node
and npm
come from the same NVM directory, the problem is solved.
The idea behind PATH is simple, but it’s easy to forget that the shell just picks the first match. We don’t usually see PATH directly, so when multiple tools fight over the same name, it feels like the machine has a mind of its own.
The other confusing part is initialization. PATH is often modified in .zshrc
, .bashrc
, or .profile
. Different shells may read different files. Graphical terminals may behave differently than login shells. The result is that the same command can resolve to different binaries depending on context. That’s why you sometimes see one version of Node in VS Code and another in the terminal.
The reason PATH confuses beginners is that it’s invisible most of the time. When you install software, you don’t usually think about where the binary ends up. But PATH is always deciding what runs. That’s why two shells can behave differently, or why VS Code might run a different Node version than your terminal.
The rule of thumb is simple: if the version doesn’t match what you installed, PATH is the first thing to check.
PATH problems aren’t limited to Node. The same thing happens with Python, Ruby, Java, and even Git. If you’ve ever typed python
and gotten version 2.7 when you expected 3.x, that’s the same bug in disguise.
This isn’t just a local annoyance. The same principle shows up everywhere.
In CI pipelines, where different agents might have different PATHs.
In Docker containers, where a base image might already include a binary you didn’t expect.
In production servers, where sysadmins and developers install different versions of the same tool.
If you don’t know which binary is being called, you can’t trust your builds. That’s true on your laptop, and it’s true in distributed systems. An engineer who understands PATH can diagnose why a build agent is using an outdated Node, or why Docker is bundling the wrong binary. An engineer who doesn’t will waste hours reinstalling tools.
The fix for conflicting Node versions is easy once you see it: pick one system to manage Node, remove the others, and control PATH ordering. The hard part is noticing that PATH is the problem at all.
Once you internalize how PATH works, these mysteries stop being mysteries. node -v
always shows the version you expect, npm
always matches, and new shells behave consistently.
The real lesson is broader: most frustrating environment bugs aren’t random. They’re the system doing exactly what you told it to — just at a layer you weren’t looking at.
Written by Alissa Nguyen
FollowAlissa Nguyen is a software engineer with main focus is on building better software with latest technologies and frameworks such as Remix, React, and TailwindCSS. She is currently working on some side projects, exploring her hobbies, and living with her two kitties.
Learn more about me
If you found this article helpful.
You will love these ones as well.
Built and designed by Alissa Nguyen a.k.a Tam Nguyen.
Copyright © 2025 All Rights Reserved.