Episode 3 — NodeJS MongoDB Backend Architecture / 3.1 — Starting with NodeJS

3.1.b — Setting Up Tools and Environment

In one sentence: A properly configured Node.js development environment with nvm, VS Code, and essential tooling eliminates friction and lets you focus on writing code instead of fighting your setup.


Navigation: ← 3.1 Overview · Next → 3.1.c Running Scripts


Table of Contents


1. Installing Node.js — The Right Way

There are multiple ways to install Node.js. Here is why each matters:

MethodProsConsRecommended?
Official installer (nodejs.org)Simple, GUI-basedOnly one version at a time; needs admin/sudoFor quick testing only
nvm (Node Version Manager)Multiple versions, easy switching, no sudomacOS/Linux only (nvm-windows for Windows)Yes — use this
fnm (Fast Node Manager)Faster than nvm, cross-platform, Rust-basedNewer, smaller communityGood alternative
Homebrew (brew install node)Easy on macOSOnly one version, can conflict with nvmNot recommended
System package manager (apt, yum)Native to OSOften outdated versionsNot recommended
DockerIsolated, reproducibleOverhead for local devFor CI/CD or containers

The golden rule

Never install Node.js globally with sudo. Use nvm. It installs Node.js in your home directory — no permission issues, ever.


2. nvm — Node Version Manager

Why nvm?

Different projects may require different Node.js versions. nvm lets you install and switch between them in seconds.

Installing nvm (macOS / Linux)

# Install nvm (check https://github.com/nvm-sh/nvm for latest version)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# Restart your terminal, then verify
nvm --version
# Output: 0.39.7

Installing nvm-windows (Windows)

# Download installer from: https://github.com/coreybutler/nvm-windows/releases
# Run the installer (.exe)
# Restart terminal

nvm version

Essential nvm commands

# Install the latest LTS version
nvm install --lts

# Install a specific version
nvm install 20.11.0

# Install the latest version (Current — may be unstable)
nvm install node

# List all installed versions
nvm ls
#   v18.19.0
#   v20.11.0    ← currently active
# -> v22.0.0
# default -> 20.11.0

# Switch to a different version
nvm use 18
# Now using node v18.19.0 (npm v10.2.3)

# Set a default version (used when opening new terminals)
nvm alias default 20
# default -> 20 (-> v20.11.0)

# Uninstall a version you no longer need
nvm uninstall 16.20.0

# Show the currently active version
nvm current
# v20.11.0

# Run a single command with a specific version (without switching)
nvm exec 18 node -e "console.log(process.version)"
# v18.19.0

nvm cheat sheet

CommandAction
nvm install --ltsInstall latest LTS
nvm install 20Install latest Node.js 20.x
nvm use 20Switch to Node.js 20.x
nvm lsList installed versions
nvm ls-remote --ltsList all available LTS versions
nvm alias default 20Set default version for new shells
nvm currentShow active version
nvm uninstall 16Remove a version

3. Verifying Your Installation

After installing Node.js, verify everything works:

# Check Node.js version
node -v
# v20.11.0

# Check npm version (comes bundled with Node.js)
npm -v
# 10.2.4

# Check npx version (comes with npm 5.2+)
npx -v
# 10.2.4

# Quick test — run JavaScript from the command line
node -e "console.log('Node.js is working! Version:', process.version)"
# Node.js is working! Version: v20.11.0

# Check installation location (should be in ~/.nvm, NOT /usr/local)
which node
# /Users/yourname/.nvm/versions/node/v20.11.0/bin/node

# Full environment details
node -p "process.arch + ' ' + process.platform"
# arm64 darwin   (on Apple Silicon Mac)
# x64 linux      (on Linux)

Troubleshooting common issues

ProblemSolution
nvm: command not foundRestart terminal; check ~/.bashrc or ~/.zshrc for nvm init lines
node: command not foundRun nvm install --lts then nvm use --lts
Permission errors with npmYou are probably using system Node — switch to nvm
Wrong version after switchingOpen a new terminal tab; nvm is shell-specific

4. Understanding LTS vs Current

┌─────────────────────────────────────────────────────────────┐
│               NODE.JS RELEASE SCHEDULE                       │
│                                                             │
│  Even-numbered versions (18, 20, 22) → become LTS           │
│  Odd-numbered versions (19, 21, 23) → Current only, no LTS  │
│                                                             │
│  Timeline for a version (e.g., Node 20):                     │
│                                                             │
│  Apr 2023          Oct 2023           Apr 2025    Apr 2026  │
│  ─────┬──────────────┬──────────────────┬──────────┬──────  │
│       │   Current    │   Active LTS     │Maint LTS │ EOL    │
│       │  (6 months)  │  (12 months)     │(18 mons) │        │
│       │  New features│  Bug+security    │ Security │ Done   │
│       │  may break   │  fixes only      │ only     │        │
│                                                             │
│  RULE: Use LTS for production. Use Current for experiments. │
└─────────────────────────────────────────────────────────────┘
Release TypeUse WhenExample
LTS (Long-Term Support)Production apps, team projects, learningNode 20.x, Node 22.x
CurrentTesting new features, contributing to Node.jsNode 23.x

5. Choosing and Configuring VS Code

Why VS Code?

VS Code is the most popular editor for Node.js development. It is free, open-source, fast, and has an enormous extension ecosystem.

Essential extensions for Node.js

ExtensionWhat It Does
ESLintReal-time linting — catches errors and enforces code style as you type
PrettierAuto-formats code on save — consistent formatting across the team
REST ClientSend HTTP requests directly from .http files in VS Code
Thunder ClientGUI-based API tester (like Postman, but inside VS Code)
Error LensShows errors and warnings inline next to the code
Path IntellisenseAuto-completes file paths in require() and import
DotENVSyntax highlighting for .env files
GitLensShows Git blame, history, and diffs inline
npm IntellisenseAuto-completes package names in require() / import
Code Spell CheckerCatches typos in variable names and comments

Recommended VS Code settings for Node.js

Create or edit .vscode/settings.json in your project:

{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.tabSize": 2,
  "editor.wordWrap": "on",
  "editor.bracketPairColorization.enabled": true,
  "files.trimTrailingWhitespace": true,
  "files.insertFinalNewline": true,
  "files.exclude": {
    "node_modules": true
  },
  "javascript.updateImportsOnFileMove.enabled": "always",
  "terminal.integrated.defaultProfile.osx": "zsh"
}

The integrated terminal

VS Code Shortcut to open terminal:
  macOS:    Ctrl + ` (backtick)
  Windows:  Ctrl + ` (backtick)
  Linux:    Ctrl + ` (backtick)

Split terminal:    Cmd/Ctrl + Shift + 5
New terminal:      Cmd/Ctrl + Shift + `
Kill terminal:     Click trash icon

6. API Testing Tools — Postman and Alternatives

When building Node.js APIs, you need a way to send requests and inspect responses.

ToolTypeBest For
PostmanDesktop appTeam collaboration, collections, environments
Thunder ClientVS Code extensionQuick testing without leaving the editor
REST ClientVS Code extensionVersion-controllable .http files
curlCLI toolScripting, CI/CD pipelines
InsomniaDesktop appClean UI, GraphQL support

Quick curl examples (built into every terminal)

# GET request
curl http://localhost:3000/api/users

# GET with headers
curl -H "Authorization: Bearer token123" http://localhost:3000/api/me

# POST with JSON body
curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Arjun", "email": "arjun@example.com"}'

# See full request/response headers
curl -v http://localhost:3000/api/health

REST Client example (.http file in VS Code)

### Get all users
GET http://localhost:3000/api/users
Content-Type: application/json

### Create a new user
POST http://localhost:3000/api/users
Content-Type: application/json

{
  "name": "Arjun",
  "email": "arjun@example.com"
}

### Get user by ID
GET http://localhost:3000/api/users/1
Authorization: Bearer {{token}}

7. Terminal Basics for Node.js Development

These commands will be used constantly in Node.js development:

File and directory commands

# Create a directory
mkdir my-project

# Create nested directories
mkdir -p src/routes/api

# Navigate into directory
cd my-project

# Go back one level
cd ..

# List files (including hidden)
ls -la

# Create a file
touch index.js

# Remove a file
rm unwanted-file.js

# Remove a directory and its contents
rm -rf node_modules

# Print current directory
pwd
# /Users/yourname/projects/my-project

# Clear terminal
clear    # or Cmd+K on macOS

Node-specific terminal commands

# Run a JavaScript file
node index.js

# Run with auto-restart on file changes (Node 18+)
node --watch index.js

# Run with environment variable
PORT=4000 node server.js

# Run with .env loading (Node 20.6+)
node --env-file=.env server.js

# Check syntax without running
node --check index.js

# Run inline JavaScript
node -e "console.log(2 + 2)"

# Print an expression's result
node -p "Math.random()"

8. Creating Your First Project Directory

Let us set up a proper project from scratch:

# Step 1: Create and enter the project directory
mkdir my-first-node-project
cd my-first-node-project

# Step 2: Initialize the project (creates package.json)
npm init -y

# Step 3: Create a .gitignore file
echo "node_modules/
.env
.DS_Store
dist/
coverage/" > .gitignore

# Step 4: Create the main file
touch index.js

# Step 5: Create an .nvmrc file (for team consistency)
echo "20" > .nvmrc

# Step 6: Initialize git
git init

# Your project structure now:
# my-first-node-project/
# ├── .git/
# ├── .gitignore
# ├── .nvmrc
# ├── index.js
# └── package.json

Your first index.js

// index.js — Your first Node.js program
console.log('Namaste Duniya! Welcome to Node.js');
console.log('Node version:', process.version);
console.log('Platform:', process.platform);
console.log('Current directory:', __dirname);
# Run it
node index.js
# Namaste Duniya! Welcome to Node.js
# Node version: v20.11.0
# Platform: darwin
# Current directory: /Users/yourname/my-first-node-project

9. The .nvmrc File for Team Consistency

When multiple developers work on the same project, they must use the same Node.js version to avoid "works on my machine" problems.

Creating .nvmrc

# Option 1: Specify a major version (recommended — auto-picks latest 20.x)
echo "20" > .nvmrc

# Option 2: Specify an exact version
echo "20.11.0" > .nvmrc

# Option 3: Use the keyword
echo "lts/*" > .nvmrc

Using .nvmrc

# When you cd into a project with .nvmrc:
nvm use
# Found '/Users/yourname/my-project/.nvmrc' with version <20>
# Now using node v20.11.0 (npm v10.2.4)

# If that version isn't installed yet:
nvm install
# Installs the version from .nvmrc, then switches to it

Auto-switching (add to ~/.zshrc or ~/.bashrc)

# Add this to your shell profile for automatic version switching
# when you cd into a directory with .nvmrc
autoload -U add-zsh-hook
load-nvmrc() {
  local nvmrc_path="$(nvm_find_nvmrc)"
  if [ -n "$nvmrc_path" ]; then
    local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
    if [ "$nvmrc_node_version" = "N/A" ]; then
      nvm install
    elif [ "$nvmrc_node_version" != "$(nvm version)" ]; then
      nvm use
    fi
  elif [ -n "$(PWD=$OLDPWD nvm_find_nvmrc)" ] && [ "$(nvm version)" != "$(nvm version default)" ]; then
    echo "Reverting to nvm default version"
    nvm use default
  fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc

10. Node.js REPL — Interactive Playground

REPL stands for Read-Eval-Print-Loop. It is an interactive shell where you can type JavaScript and see results immediately.

Starting the REPL

# Just type 'node' with no arguments
node

# You'll see:
# Welcome to Node.js v20.11.0.
# Type ".help" for more information.
# >

Using the REPL

> 2 + 2
4

> 'hello'.toUpperCase()
'HELLO'

> const greet = (name) => `Namaste, ${name}!`
undefined

> greet('Arjun')
'Namaste, Arjun!'

> Math.random()
0.7234819273645

> new Date().toISOString()
'2025-01-15T10:30:00.000Z'

// The underscore _ holds the last evaluated result
> 5 * 10
50
> _ + 1
51

// Multi-line input (REPL auto-detects unclosed brackets)
> function add(a, b) {
... return a + b;
... }
undefined
> add(10, 20)
30

REPL special commands

CommandAction
.helpShow all REPL commands
.exitExit the REPL (or press Ctrl+D)
.clearReset the REPL context (clear all variables)
.breakAbort a multi-line expression
.save filename.jsSave current REPL session to a file
.load filename.jsLoad a file into the REPL
Tab (twice)Auto-complete — shows available properties

Exploring built-in modules in the REPL

> require('os').hostname()
'MacBook-Pro.local'

> require('os').cpus().length
8

> require('path').join('src', 'routes', 'index.js')
'src/routes/index.js'

> require('crypto').randomUUID()
'f47ac10b-58cc-4372-a567-0e02b2c3d479'

// Tab-complete to explore
> require('fs').    // press Tab twice here
// Shows: readFile, writeFile, mkdir, stat, ...

11. Understanding the node Command

The node command is your gateway to running JavaScript outside the browser.

Common flags and usage

# Run a file
node app.js

# Evaluate a string of code
node -e "console.log('Hello from -e flag')"

# Print the result of an expression
node -p "1 + 1"
# 2

# Check syntax without executing
node --check app.js
# (no output = syntax is valid)

# Watch mode — auto-restart on file changes (Node 18+)
node --watch app.js

# Watch mode with specific paths
node --watch-path=./src app.js

# Enable source maps for debugging
node --enable-source-maps app.js

# Set environment variables inline
NODE_ENV=production node app.js

# Load .env file automatically (Node 20.6+)
node --env-file=.env app.js

# Increase memory limit (default ~1.5 GB)
node --max-old-space-size=4096 app.js

# Enable experimental features
node --experimental-specifier-resolution=node app.mjs

# Show V8 and Node.js version details
node -p "process.versions"
# {
#   node: '20.11.0',
#   v8: '11.8.172.17',
#   uv: '1.46.0',
#   openssl: '3.0.12',
#   ...
# }

node command cheat sheet

CommandWhat It Does
node file.jsRun a JavaScript file
nodeStart the REPL
node -vPrint Node.js version
node -e "code"Execute inline code
node -p "expr"Evaluate and print result
node --check file.jsSyntax check without running
node --watch file.jsAuto-restart on changes
node --env-file=.env file.jsLoad environment variables

Key Takeaways

  1. Use nvm to install and manage Node.js versions — never install globally with sudo or Homebrew.
  2. Always use LTS versions for production and learning; Current versions are for experiments.
  3. VS Code with ESLint, Prettier, and REST Client/Thunder Client is the recommended setup for Node.js development.
  4. Postman or curl are essential for testing APIs you build — learn both GUI and CLI approaches.
  5. .nvmrc ensures every team member uses the same Node.js version — commit it to your repository.
  6. The REPL (node with no arguments) is a fast way to test snippets, explore modules, and debug.
  7. node --watch (Node 18+) replaces the need for nodemon in many cases — auto-restarts on file changes.
  8. node --env-file (Node 20.6+) loads .env files natively — no need for the dotenv package in simple cases.

Explain-It Challenge

Can you set up a brand new Node.js project from scratch — install nvm, pick an LTS version, create a project directory, initialize package.json, create .nvmrc, and run a "Hello World" — all without looking at any documentation? Time yourself and aim for under 3 minutes.


Navigation: ← 3.1 Overview · Next → 3.1.c Running Scripts with Node.js