Course
Node.js
206 lessons across 14 modules
Beginner to production, assuming JavaScript and ES6+. The runtime and event loop, modules and npm, the core library, files and streams, async, HTTP from scratch, Express, REST design, PostgreSQL, auth and security, production operations, and testing - ending in a multi-tenant learning platform API. The road is laid out in full; lessons are being written one at a time.
Node.js Fundamentals
What Node is, and getting a first program running
Prerequisite: the JavaScript course →What is Node.js?
1A JavaScript runtime built for servers and tools, not a framework.
The same function running outside a browser
Why Node.js?
2Non-blocking I/O, one language front to back, and a huge ecosystem.
A server holding ten thousand idle connections cheaply
Node.js vs Browser JavaScript
3Same language, different globals - no DOM, but a file system.
window missing and process present
Node.js Use Cases
4Where it shines, and the CPU-heavy work where it does not.
An API server against a video encoder
Node.js Architecture Overview
5V8, libuv, and bindings - the three layers in one picture.
Following fs.readFile down through the layers
Installing Node.js
6LTS against current, and installing without admin rights.
Choosing a version for a production server
Node.js Version Management
7nvm and friends, and pinning the version per project.
An .nvmrc that makes every machine agree
Running Your First Node.js Program
8A script, run from the terminal, printing to stdout.
Reading a command-line argument and greeting it
Node.js REPL
9The interactive prompt, and what it is actually good for.
Checking how a built-in behaves in five seconds
node Command
10Flags worth knowing - watch, env-file, inspect.
Restarting on save without installing anything
Understanding package.json
11Reading one to understand what a project is and how to run it.
Opening an unfamiliar repo and knowing where to start
Node.js Project Structure
12Where code, config, and tests live in a small project.
A layout that still makes sense at fifty files
Node.js Runtime and Architecture
Why Node behaves differently from other backends
Watch the event loop step by step →Node.js Runtime
13Everything around the engine that makes JavaScript a server language.
What Node adds that V8 alone does not have
V8 JavaScript Engine
14Parsing, JIT compilation, and garbage collection.
A function that gets faster after it has run a few times
Event-Driven Architecture
15Reacting to events rather than waiting in a loop.
A server that does nothing until a request arrives
Single-Threaded Model
16One thread for your code - and what that makes easy and hard.
No locks needed, and one slow loop blocking everyone
Non-Blocking I/O
17Starting work and being told when it is done.
Three file reads overlapping instead of queueing
Event Loop
18The phases the runtime cycles through, and what runs in each.
Timers, poll, check, and close, drawn as a cycle
Call Stack
19The work happening right now, and why it must empty before anything else runs.
A callback that waits for a long function to finish
Callback Queue
20Where finished I/O waits for the stack to clear.
A completed read queued behind a busy loop
Microtask Queue
21The queue that drains completely between every other step.
Promise callbacks jumping ahead of a timer
libuv
22The C library behind the loop, and its thread pool.
Why four slow crypto calls run in parallel and a fifth waits
Worker Threads
23Where real parallelism fits in the architecture.
A second thread with its own event loop
Node.js Process Model
24One process, its memory, and scaling out with more of them.
One process per core behind a load balancer
Modules and NPM
Splitting code into files, and depending on other people
Node.js Modules
25Every file is a module with its own scope.
A variable that does not leak between files
CommonJS
26The original Node module system, still everywhere.
Reading a CommonJS file from an older package
require()
27Synchronous loading, resolution rules, and the module cache.
A module that runs once however many times it is required
module.exports
28What a module hands back, and the exports shorthand trap.
Reassigning exports and exporting nothing
ES Modules
29The standard module system, and turning it on in Node.
"type": "module" and the .mjs extension
import
30Static and dynamic imports, and file extensions being required.
An import that fails for want of ".js"
export
31Named and default exports from an ES module.
A module with a small, deliberate public surface
CommonJS vs ES Modules
32The differences that bite - __dirname, top-level await, interop.
A package that one system can load and the other cannot
Built-in Modules
33What ships with Node, and the node: prefix.
node:fs against an npm package called fs
NPM
34The registry and the client, and what installing really does.
Tracing where a package lands on disk
package.json
35Every field that matters - scripts, engines, exports, type.
An exports map that hides internal files
Dependencies
36What your code needs to run in production.
A production install missing a package it needed
Dev Dependencies
37Tools needed only to build and test.
A test runner that should never reach a server
Semantic Versioning
38Major, minor, patch - and what ^ and ~ allow.
A caret range that pulled in a breaking change
package-lock.json
39Exact versions, committed, so every install is identical.
npm ci against npm install in a pipeline
NPM Scripts
40Naming the commands a project runs, and pre and post hooks.
dev, build, test, and start as the project contract
npx
41Running a package without installing it globally.
Scaffolding a project with a one-off command
Node.js Core Modules
The standard library that ships with every install
path
42Building paths that work on every operating system.
A hard-coded slash that breaks on Windows
os
43CPU count, memory, and platform details.
Sizing a worker pool from the core count
url
44Parsing and building URLs with the WHATWG URL class.
Reading query parameters without string splitting
events
45EventEmitter - the pattern much of Node is built on.
A job queue that emits started, done, and failed
util
46promisify, inspect, and types - the useful few.
Turning a callback API into one you can await
crypto
47Hashing, random values, and what not to build yourself.
A secure random token for a password reset
process
48Arguments, exit codes, signals, and the current process.
Exiting with a non-zero code so a script fails a pipeline
Environment Variables
49process.env - reading configuration from outside the code.
A port that differs per environment
child_process
50Running other programs, and the shell-injection risk.
exec with user input, and the safer execFile
buffer
51Raw binary data, and encodings.
A UTF-8 string and its byte length disagreeing
File System and Streams
Reading, writing, and processing data too big for memory
File System Module
52The three APIs - callback, sync, and promises - and which to use.
The same read written all three ways
Reading Files
53Reading text and binary, and handling a missing file.
A config file that may not exist yet
Writing Files
54Writing, appending, and writing atomically.
A crash mid-write leaving a half-written file
Updating Files
55Read, change, write - and the race when two do it at once.
Two processes updating one JSON file
Deleting Files
56Removing files and directories safely.
A recursive delete that needs a guard
Synchronous vs Asynchronous File Operations
57Sync is fine at startup and a disaster in a request handler.
A readFileSync freezing every other request
Promises API
58fs/promises with async/await, the modern default.
Reading a directory of files concurrently
Buffers
59Buffers as the unit of file I/O, and when to decode them.
A file read that returns bytes, not text
Streams
60Processing data piece by piece instead of all at once.
A 4 GB file handled in a few megabytes of memory
Readable Streams
61Data events, async iteration, and paused against flowing.
Reading a large log with for await
Writable Streams
62Writing in chunks, and backpressure.
A fast producer and a slow disk, handled correctly
Transform Streams
63Changing data as it flows through.
Uppercasing a file without loading it
Piping
64pipeline(), and why it beats pipe() for error handling.
Compressing a file in one line that cleans up on failure
Large File Processing
65Streams, lines, and batches, applied to a real file.
A CSV processor that validates and transforms a million rows
Asynchronous Node.js
Writing async code, and predicting when it runs
Synchronous vs Asynchronous
66Blocking against non-blocking, in a server specifically.
One slow handler slowing every user
Callbacks
67Error-first callbacks, the original Node convention.
Reading the (err, data) signature correctly
Callback Hell
68Nesting, lost errors, and why the pattern had to change.
Four nested reads and an error nobody handles
Promises
69Values that arrive later, chained and flattened.
The same four reads, flat
async/await
70Promises that read top to bottom.
A sequential await that should have been parallel
Error Handling
71try/catch with await, and unhandled rejections crashing the process.
A forgotten await turning an error into a crash
Promise.all
72Running in parallel, and failing fast.
Three queries at once, one failure losing the rest
Promise.allSettled
73Every result, success or failure.
A batch job reporting exactly which items failed
Promise.race
74The first to settle wins - and building a timeout from it.
A request abandoned after two seconds
Event Loop
75Reading code and predicting the order it will actually run in.
A six-line puzzle, answered by reasoning rather than running
Timers
76What a timer guarantees - a minimum, never an exact time.
A 100 ms timer firing at 140 ms under load
setTimeout
77Delaying work, and setTimeout zero not meaning now.
A zero delay running after everything already queued
setImmediate
78Running after I/O, in the check phase.
setImmediate beating setTimeout inside an I/O callback
process.nextTick
79Before everything else - and starving the loop with it.
A recursive nextTick that stops I/O entirely
Microtasks
80Promise callbacks and queueMicrotask, and when they drain.
A microtask running before a timer due now
Macrotasks
81Timers, I/O, and immediates - one at a time between microtasks.
The full ordering of all five scheduling tools
HTTP and Web Servers
The protocol, and a server with no framework
HTTP Fundamentals
82Request and response, over a connection, as text.
A raw HTTP request typed by hand
HTTP Methods
83GET, POST, PUT, PATCH, DELETE - and safety and idempotence.
Why a retried POST can charge a card twice
HTTP Status Codes
84What the classes mean - 2xx, 3xx, 4xx, 5xx.
A 200 with an error body, and why that is wrong
HTTP Headers
85Metadata about the message - content, caching, auth.
A missing Content-Type breaking a JSON client
Request
86The incoming request object - method, URL, headers, body stream.
Logging everything a request carries
Response
87Status, headers, body, and ending it exactly once.
A response never ended, and a client hanging
Creating an HTTP Server
88http.createServer with no framework at all.
A JSON endpoint in twelve lines
Routing
89Matching method and path by hand.
A router that shows exactly what Express saves you
Query Parameters
90Parsing the query string with URL.
A search endpoint reading page and limit
Path Parameters
91Extracting ids from the path yourself.
Matching /users/42 without a library
Request Body
92The body arrives as a stream, and must be collected.
Reading a POST body chunk by chunk
JSON
93Parsing input safely and serialising output.
Invalid JSON crashing a server that did not catch it
Content Types
94Telling the client what you sent, and checking what you got.
A form post that is not JSON
HTTP Error Handling
95Failing with the right status and a useful body.
An unexpected error becoming a clean 500
Express.js
The framework most Node APIs are built on
What is Express?
96A thin layer over http - routing and middleware.
The Module 7 server rewritten in a third of the code
Express Application
97Creating the app, and separating it from listening.
An app exported without listening, so tests can use it
Routes
98Method and path handlers, and order mattering.
A catch-all route declared too early
Route Parameters
99req.params, and Express doing the matching for you.
/users/:id with the id already extracted
Query Parameters
100req.query, and every value arriving as a string.
A page number that is "2", not 2
Request Body
101Body-parsing middleware, and size limits.
A body that is undefined because no parser ran
Middleware
102Functions in a chain, and next().
A request passing through four middleware in order
Custom Middleware
103Writing your own for logging, timing, and auth.
A request-id middleware used by every log line
Router
104Grouping routes into mountable modules.
A users router mounted at /api/users
Controllers
105Keeping handlers thin, and HTTP out of business logic.
A handler that parses, calls a service, and responds
Error Middleware
106The four-argument handler, and one place for every error.
A central handler mapping errors to statuses
Async Error Handling
107Rejected promises in handlers, and Express 5 catching them.
An async throw that hangs a request in Express 4
Static Files
108Serving files, and caching headers for them.
A public folder with long-lived cache headers
CORS
109Configuring the cors middleware for the origins you allow.
A frontend on another port blocked, then allowed
Request Validation
110Validation middleware that rejects bad input before a handler runs.
A schema check returning 400 with field errors
Express Project Structure
111Routes, controllers, services, repositories - and why.
A layout where each layer has one job
REST API Development
Designing an API other people can use
REST Architecture
112Resources, representations, and statelessness.
An RPC-style API redesigned around resources
Resource Design
113Nouns, nesting, and plural collection names.
/courses/12/lessons against /getLessonsForCourse
GET
114Reading collections and single resources, safely.
A list and a detail endpoint for one resource
POST
115Creating, and returning 201 with a Location.
A create endpoint that tells you where the new thing is
PUT
116Replacing a resource entirely, idempotently.
A PUT that wiped fields the client did not send
PATCH
117Partial updates, and which fields are allowed to change.
Updating one field without touching the rest
DELETE
118Removing, soft deletes, and 204.
A delete that can be undone
HTTP Status Codes
119Choosing the right code when designing an API.
400, 401, 403, 404, 409, and 422 each used correctly
Pagination
120Offset against cursor, and returning the next link.
A cursor that stays stable while rows are inserted
Filtering
121Filter parameters that map cleanly to queries.
?status=active&level=beginner
Sorting
122Sort parameters, allowed fields, and a stable tiebreaker.
?sort=-createdAt with a whitelist behind it
Searching
123Text search that stays fast, and when it needs its own index.
A LIKE query that works until the table grows
API Validation
124Validation errors as part of the API contract.
A consistent error shape clients can render
API Error Handling
125One error format across every endpoint.
Problem Details responses from a single handler
API Response Standards
126Envelopes, field naming, dates, and consistency.
Two endpoints that disagree about date formats
API Documentation
127Documentation developers will actually read.
An example request and response for every endpoint
OpenAPI and Swagger
128A machine-readable spec, and the tools it unlocks.
Interactive docs and a generated client from one file
Database Integration
PostgreSQL first, MongoDB as the alternative
SQL in depth →Database Fundamentals
129Relational against document, and choosing for the data.
The same course data modelled both ways
Node.js and PostgreSQL
130The pg driver, and running a first query.
Listing courses from a real table
Node.js and MongoDB
131The official driver, and where documents fit better.
An activity feed stored as documents
Database Connection
132Connecting once at startup, and failing loudly if you cannot.
A server that refuses to start without its database
Connection Pooling
133Reusing connections, and sizing the pool.
A pool exhausted by a leaked client
CRUD Operations
134Create, read, update, and delete in SQL from Node.
A users table with all four operations
Transactions
135All or nothing - and releasing the client on every path.
An enrollment and a payment that must both succeed
SQL Injection
136Parameterised queries, and never concatenating input.
A search box that dropped a table
ORM Concepts
137What an ORM does for you, and what it hides.
One ORM call and the several queries it really ran
Prisma
138Schema-first, type-safe access, and generated clients.
A schema file producing a typed client
Sequelize
139Model-first ORM, still common in existing code.
Reading and maintaining a Sequelize model
Migrations
140Versioned schema changes, applied the same way everywhere.
Adding a column without downtime
Relationships
141One-to-many, many-to-many, and loading them efficiently.
Courses with lessons without an N+1
Database Error Handling
142Unique violations, timeouts, and mapping them to HTTP.
A duplicate email returning 409 rather than 500
Repository Pattern
143Data access behind an interface, so services stay clean.
Swapping the database under a service that never noticed
Authentication and Security
Who the user is, what they may do, and keeping attackers out
Authentication vs Authorization
144Who you are against what you may do.
A logged-in user who still gets a 403
User Registration
145Creating accounts, validating input, and duplicate emails.
A sign-up endpoint that does not leak who is registered
Password Hashing
146Why hashing, why slow, and why never encryption.
A leaked table of fast hashes cracked in minutes
bcrypt
147Salts, cost factors, and comparing safely.
Choosing a cost factor for your hardware
Login
148Verifying credentials without revealing which part was wrong.
One error message for a bad email and a bad password
JWT
149Signed claims - what they prove and what they do not.
A token that cannot be revoked before it expires
Access Tokens
150Short-lived tokens, verified on every request.
An auth middleware that sets req.user
Refresh Tokens
151Long-lived, stored server-side, and rotated on use.
Detecting a stolen refresh token by reuse
Cookies
152httpOnly, Secure, SameSite - each one earning its place.
A session cookie JavaScript cannot read
Sessions
153Server-side sessions, and when they beat tokens.
Logging a user out everywhere instantly
Protected Routes
154Requiring authentication, applied once per router.
A whole router guarded by one line
RBAC
155Roles mapped to permissions, checked on the server.
An admin-only route enforced by middleware
Permissions
156Finer than roles - and checking ownership of the resource.
A user editing only their own records
CORS
157What CORS protects, and the many things it does not.
Why a permissive CORS policy is not a vulnerability by itself
Helmet
158Security headers set sensibly in one line.
The headers Helmet adds, read one by one
Rate Limiting
159Slowing brute force and abuse, per user and per IP.
A login endpoint that locks out after repeated failures
Input Validation
160Validation as a security control, not just a courtesy.
Rejecting unexpected fields before they reach the database
SQL Injection
161Injection in the wider threat model - SQL, NoSQL, and commands.
A MongoDB query injected through a JSON body
XSS
162The server role in XSS - escaping and content security policy.
A stored comment that runs script in other browsers
CSRF
163Cookie authentication and forged requests.
SameSite and a token closing the hole
Security Best Practices
164The checklist worth running before every release.
An audit of a real API against the list
Production Node.js
Configuration, observability, scaling, and deployment
Node performance in depth →Environment Configuration
165One build, configured per environment from outside.
The same image running in staging and production
.env
166Local configuration files, and never committing them.
A .env.example that documents every variable
Configuration Management
167Validating configuration once, at startup, with types.
A missing variable failing at boot rather than at 2am
Logging
168Structured logs, levels, and what never to log.
A JSON log line you can search by request id
Winston
169A configurable logger with transports and formats.
Pretty logs in development, JSON in production
Error Monitoring
170Capturing errors with context and alerting on them.
An error report with the request that caused it
Health Checks
171Liveness against readiness, and what each should test.
A readiness check that fails while the database is down
Graceful Shutdown
172Finishing in-flight requests before exiting.
A deploy that drops no requests
Process Management
173Keeping a process alive, and restarting it when it dies.
A crash recovered from in under a second
PM2
174A process manager for servers without an orchestrator.
Running, restarting, and tailing logs on one VM
Clustering
175One process per core, sharing a port.
Using all eight cores instead of one
Worker Threads
176Moving CPU-bound work off the event loop in production.
Image resizing that no longer blocks the API
Caching
177What to cache, for how long, and invalidating it.
A slow endpoint served from cache in two milliseconds
Redis
178An in-memory store for caching, sessions, and rate limits.
A cache shared by every instance of the API
Message Queues
179Moving slow work out of the request path.
An email sent after the response, not before it
RabbitMQ
180Queues, exchanges, acknowledgements, and retries.
A worker that retries a failed job without losing it
Dockerizing Node.js
181Small, secure images with multi-stage builds.
An image that went from 1 GB to 150 MB
Node.js in Kubernetes
182Probes, resource limits, and shutdown signals in a cluster.
A pod killed mid-request, and the fix
CI/CD
183Lint, test, build, and deploy on every merge.
A pipeline that blocks a failing build from shipping
Production Best Practices
184The decisions worth making before launch, not after.
A pre-launch review of a real service
Testing Node.js
Its own module, not a footnote to production
Testing Fundamentals
185What a test buys you, and the tests that buy nothing.
A test that breaks on every refactor and catches no bugs
Unit Testing
186Testing one unit in isolation, fast.
A pricing function tested at every boundary
Jest and Vitest
187Runners, matchers, and the node:test built-in.
The same test in all three
Testing Services
188Business logic tested without HTTP or a database.
A service tested against a fake repository
Testing Controllers
189Checking the translation between HTTP and services.
A controller that maps a service error to 404
Mocking
190Replacing what is slow or external - and not mocking too much.
A test so heavily mocked it tests nothing
API Testing
191Testing endpoints as a client would see them.
Status, headers, and body asserted together
Supertest
192Driving an Express app in tests without opening a port.
The exported app from lesson 97 paying off
Integration Testing
193Several layers together, where the real bugs are.
Register, log in, and fetch in one test
Database Testing
194A real database per run, and resetting it between tests.
Tests in a transaction that is rolled back
Test Coverage
195What coverage measures, and what it cannot.
100 per cent coverage and a bug still shipping
Test Environment
196Configuration, fixtures, and tests that run anywhere.
A suite that passes on a laptop and in CI alike
Real-World Project
A multi-tenant learning platform API
Architecture and Setup
197Express, PostgreSQL, and Redis, with the layered src/ structure.
config, routes, controllers, services, repositories - agreed first
Authentication
198Registration, login, tokens, and refresh.
A full auth flow with rotated refresh tokens
Users and Tenants
199Every query scoped to a tenant, enforced below the service layer.
A repository that cannot forget the tenant id
Roles and Permissions
200Per-tenant roles, and middleware that enforces them.
The same user an admin in one tenant and a learner in another
Courses, Modules, and Lessons
201A three-level hierarchy with relationships loaded efficiently.
A course outline fetched in two queries, not two hundred
Enrollments and Progress
202Writes that must be correct under concurrency.
A lesson completed twice counted once
Quizzes
203Scoring on the server, never trusting the client.
A submission that cannot be tampered with
Caching with Redis
204Caching the hot reads and invalidating them correctly.
A course page cached until its content changes
Testing the API
205Integration tests across auth, tenancy, and progress.
A test proving one tenant cannot read another
Deployment and Review
206Dockerised, deployed, monitored, and reviewed against the plan.
The finished API, and what you would change next time