Mastering Node.js Installation on Linux: Efficient Steps for a Clean Setup
Installing Node.js via a Linux package manager (apt
, yum
, etc.) often introduces unwanted friction. Version drift, global npm permission headaches, and mismatches with production workloads are common pain points—many teams discover this only after tangled upgrades or broken builds.
The reality: professional teams use Node Version Manager (NVM) to install and switch Node.js versions per-project, avoiding system-wide breakage while simplifying local and CI workflows.
Why Not Use the Distro Packages?
Table: System package limitations
Approach | Typical Version | Upgrade Path | Multi-Version Support | Pros | Cons |
---|---|---|---|---|---|
apt install nodejs | v10.x / v12.x | Tied to distro | None | Quickest initial install | Often outdated, system-wide impact |
NVM | Any | Simple, per-user | First-class | Flexible, dev-friendly | Requires curl/git, not system-wide |
Default distro sources may lag several LTS releases behind. For example, Ubuntu 22.04’s repo provides Node.js 12.x—obsolete for many enterprise toolchains. Upgrading triggers dependency churn. Not a risk you want in your CI pipeline.
Step 1: Remove Conflicting Node.js Installs
First, eliminate any legacy Node.js artifacts from earlier installations. Residual binaries in /usr/bin
frequently override intended versions.
sudo apt-get purge nodejs npm -y
sudo apt-get autoremove -y
hash -r # Clear shell's command cache
Note: On RHEL/CentOS, replace apt-get
with yum remove nodejs npm
or similar.
Step 2: Install NVM (Node Version Manager)
Latest NVM stable release as of this writing: v0.39.3. Install with:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
Or, for admins wary of remote scripts:
- Download the install script, inspect, and then run manually.
After installation, ensure your shell session loads NVM. For Bash:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
Or, simply open a new terminal. Verify installation:
command -v nvm
# Expected output: nvm
Step 3: Install a Stable Node.js Version
NVM simplifies version pinning:
nvm install --lts # Installs the latest LTS (e.g., v18.16.0 as of 2024-06)
nvm install 20.10.0 # Exact release, if project requires it
Set project-default:
nvm alias default 18.16.0
Gotcha: NVM does not auto-switch Node for new terminals unless configured in your shell. See the tip below for .nvmrc
handling.
Inspect the installed versions:
nvm ls
Step 4: Switching Between Node.js Versions
Switch Node.js in the current shell (useful when dealing with legacy services):
nvm use 16.20.0
node -v # Should return "v16.20.0"
Switch back any time. No need for sudo
, no interference with system packages. This is especially useful when testing migration between major versions.
Step 5: Project-Based Version Control with .nvmrc
At project root:
18 # Or exact version: 18.16.0
Trigger automatic switch:
nvm use
Non-obvious tip: Integrate nvm use
into build scripts or .bashrc
/.zshrc
for seamless developer onboarding. CI pipelines can load the correct version by running nvm install && nvm use
.
Advanced Notes and Trade-offs
-
npm Global Installs: NVM installs Node under
$HOME/.nvm
, sonpm install -g
never needs sudo. However, globally installed npm packages aren’t shared across Node.js versions. Reinstall as needed after upgrading Node. -
Updating npm: To avoid mismatches, manually update npm after switching Node.js versions:
npm install -g npm@latest
-
Known Issue: Extensions or system-wide CLI tools (e.g.
/usr/bin/node
invoked bysystemd
) will not use NVM-managed Node without explicit path configuration.
Example: Node Version Conflict
A common scenario:
node -v # v10.19.0
nvm use 18
node -v # v18.16.0
Node scripts in your project work, but a global tool (installed previously) still references the old version, if invoked outside nvm use
context.
Always check $PATH
.
Recap
Avoid OS package managers for Node.js unless you have a strong, audited reason. NVM is de facto standard for developer flexibility, version switching, and conflict-free upgrades. Consistency between dev, CI, and production depends on precise version pinning—.nvmrc
makes this trivial.
Critically, always verify Node.js version post-install and check for residual permissions issues with global npm packages.
For those running production workloads or containerized services, consider official Node.js Docker images for even stronger reproducibility.
No process is perfect: NVM is user-scoped, so system-level services won’t see your Node.js install without manual symlinks. Still, for nearly all development workflows, it’s by far the cleanest alternative.