Installing Node.js and npm — nvm, Versions and Verification

Before writing a single line of MERN application code you need Node.js and npm installed and working on your machine. Node.js is the runtime that powers your Express API, runs your React build tools, and executes every npm script in your project. npm (Node Package Manager) is bundled with Node.js and gives you access to over two million open-source packages. In this lesson you will install Node.js the right way using nvm (Node Version Manager), understand why version management matters, and verify your installation is ready for MERN development.

Why Use nvm Instead of the Node.js Installer?

Method Pros Cons
nodejs.org installer Simple one-click install Hard to switch versions, may require sudo for global packages, only one version at a time
nvm (recommended) Switch versions per project, no sudo needed, multiple versions side by side, .nvmrc file pins version per project Requires one extra install step
Homebrew (macOS) Easy on macOS Version switching is awkward, not designed for Node version management
Note: Node.js releases two tracks simultaneously — LTS (Long-Term Support) and Current. LTS versions (even-numbered: 18, 20, 22) receive security and bug fixes for 30 months, making them safe for production. Current versions get new features first but have a shorter support window. For MERN development always use the latest LTS — currently Node 20.
Tip: Create a .nvmrc file in the root of every project containing just the Node version number (e.g. 20). Any developer who clones the repo can run nvm use in the project root and automatically switch to the correct version. This eliminates “it works on my machine” Node version issues across teams.
Warning: On macOS and Linux, never run sudo npm install -g. If you installed Node via nvm, global npm packages install into your home directory automatically and never need sudo. Mixing sudo with npm corrupts file permissions and leads to confusing errors. If you are getting permission errors on global installs, fix the root cause (wrong Node installation method) rather than adding sudo.

Installing nvm and Node.js

# ── macOS and Linux ───────────────────────────────────────────────────────────

# Step 1: Install nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# Step 2: Restart your terminal, then verify nvm is available
nvm --version   # should print 0.39.7 or later

# Step 3: Install Node.js 20 LTS
nvm install 20

# Step 4: Set Node 20 as your default
nvm alias default 20

# Step 5: Activate it in this terminal session
nvm use 20

# ── Windows ───────────────────────────────────────────────────────────────────
# Download and install nvm-windows from:
# https://github.com/coreybutler/nvm-windows/releases
# Then open a NEW terminal (as Administrator) and run:
nvm install 20.0.0
nvm use 20.0.0

Verifying Your Installation

# Check Node.js version — should print v20.x.x
node --version

# Check npm version — should print 10.x.x
npm --version

# Run a quick Node.js sanity check
node -e "console.log('Node.js is working:', process.version)"

# Check where Node is installed (should be inside ~/.nvm, NOT /usr/local)
which node    # macOS/Linux → /Users/yourname/.nvm/versions/node/v20.x.x/bin/node
where node    # Windows    → C:\Users\yourname\AppData\Roaming\nvm\v20.x.x\node.exe

Essential npm Commands for MERN Development

Command What It Does When You Use It
npm init -y Create package.json with defaults Starting a new server or client project
npm install <pkg> Install a production dependency Adding express, mongoose, axios, etc.
npm install -D <pkg> Install a dev-only dependency Adding nodemon, eslint, jest, etc.
npm install Install all deps from package.json After cloning a repo
npm run <script> Run a script from package.json npm run dev, npm run build
npm uninstall <pkg> Remove a package Cleaning up unused dependencies
npm list --depth=0 List top-level installed packages Auditing what is installed
npm audit Check for security vulnerabilities Before deploying to production

Understanding package.json

{
  "name": "mern-blog-server",
  "version": "1.0.0",
  "description": "Express API for the MERN Blog app",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "dev":   "nodemon index.js",
    "test":  "jest"
  },
  "dependencies": {
    "cors":          "^2.8.5",
    "dotenv":        "^16.4.1",
    "express":       "^4.18.2",
    "jsonwebtoken":  "^9.0.2",
    "mongoose":      "^8.1.0",
    "nodemailer":    "^6.9.9"
  },
  "devDependencies": {
    "nodemon": "^3.0.3"
  },
  "engines": {
    "node": ">=20.0.0"
  }
}

The node_modules Directory and .gitignore

# node_modules contains every installed package and its dependencies
# It can contain 100,000+ files and hundreds of MB — NEVER commit it to Git

# Create a .gitignore in your project root
cat > .gitignore << 'EOF'
# Dependencies
node_modules/

# Environment variables — contains secrets
.env
.env.local
.env.production

# Build output
dist/
build/

# OS files
.DS_Store
Thumbs.db

# Logs
*.log
npm-debug.log*
EOF

# To restore node_modules on any machine — just run:
npm install    # reads package.json and reinstalls everything

Common Mistakes

Mistake 1 — Installing the wrong Node version

❌ Wrong — using an outdated or end-of-life Node version:

node --version   # v14.x.x — EOL since April 2023
# Many modern packages require Node 18+ and will fail to install or run

✅ Correct — always verify you are on Node 20 LTS before starting a MERN project:

nvm use 20
node --version   # v20.x.x ✓

Mistake 2 — Committing node_modules

❌ Wrong — accidentally adding node_modules to Git:

git add .   # if .gitignore is missing — adds ALL of node_modules
git commit -m "initial commit"   # repo is now hundreds of MB — unusable

✅ Correct — always create .gitignore before git init or your first git add:

echo "node_modules/" >> .gitignore
git status   # verify node_modules is not listed before committing

Mistake 3 — Confusing npm install flags

❌ Wrong — installing dev tools as production dependencies:

npm install nodemon   # nodemon ends up in dependencies — deployed to production unnecessarily

✅ Correct — dev tools that are not needed at runtime belong in devDependencies:

npm install -D nodemon   # saved under devDependencies — excluded from production builds

Quick Reference

Task Command
Install nvm (macOS/Linux) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
Install Node 20 LTS nvm install 20
Switch to Node 20 nvm use 20
Check Node version node --version
Check npm version npm --version
Initialise project npm init -y
Install package npm install express
Install dev package npm install -D nodemon
Pin Node version in project echo "20" > .nvmrc

🧠 Test Yourself

You clone a MERN project from GitHub. The repository has a package.json but no node_modules folder. What is the correct first step before running the project?