Topic 1: Introduction and Foundation
📖 7 min read · 🎯 beginner · 🧭 Prerequisites: introduction
Why this matters
Up until now, you've written JavaScript that lives in the browser — code that makes buttons click, pages move, things happen on screen. But here's the thing — that same language you already know can also run on a server, handling requests, talking to databases, powering entire backends. That's what Node.js unlocks. It takes JavaScript out of the browser and lets it run anywhere. By the end of this lesson, you'll have a real web server running on your own machine, written in JavaScript you already understand.
What You'll Learn
- What Node.js is and why it was built, including its key architectural features
- How to install Node.js and NPM and verify both are working
- How to scaffold a project, write an entry-point file, and run it
- How to use core modules (
http,fs,path), install third-party modules via NPM (express), and build custom reusable modules - How to write asynchronous Node.js code using callbacks, Promises, and async/await
The Analogy
Think of a traditional restaurant where every waiter handles one table at a time — when your order goes to the kitchen, your waiter stands idle at the pass waiting for it, blocking everyone else. Node.js runs its kitchen like a ticket system instead: the waiter drops your order, immediately takes the next table's drinks order, and comes back only when the kitchen rings the bell. That bell is the event loop — the single thread that coordinates everything without ever standing around waiting. Because nothing blocks, the restaurant handles hundreds of tables with a skeleton crew, and that is exactly why Node.js excels at network-heavy, I/O-bound workloads.
Chapter 1: Introduction to Node.js
Node.js is an open-source, cross-platform runtime environment that allows developers to execute JavaScript code outside of a web browser. It is built on Chrome's V8 JavaScript engine and is designed to build scalable network applications.
Key Features of Node.js
- Asynchronous and Event-Driven — Node.js uses a non-blocking, event-driven architecture for handling multiple requests efficiently.
- Single-Threaded — Node.js operates on a single thread using non-blocking I/O calls, making it lightweight and predictable under load.
- Fast Execution — Built on the V8 engine, Node.js compiles JavaScript directly to machine code for rapid execution.
- NPM (Node Package Manager) — Node.js ships with NPM, providing access to a vast registry of open-source packages that can be installed with a single command.
flowchart LR
Client -->|Request| EventLoop["Event Loop (single thread)"]
EventLoop -->|I/O task| WorkerPool["Worker Pool / OS Async I/O"]
WorkerPool -->|Callback| EventLoop
EventLoop -->|Response| Client
Chapter 2: Setting Up Node.js
Install Node.js from the official website at https://nodejs.org/. The installer bundles both Node.js and NPM automatically. After installation, verify both tools are available:
node -v # check the installed Node.js version
npm -v # check the installed NPM version
You should see version numbers printed for both. If you see a "command not found" error, re-run the installer and ensure it was added to your system PATH.
Chapter 3: Creating a Simple Node.js Application
Step 1 — Initialize a Node.js Project
mkdir my-node-app
cd my-node-app
npm init -y
npm init -y creates a package.json file with default settings — this file is the manifest for your project: it records the project name, version, entry point, and all future dependencies.
Step 2 — Create an Entry Point
Create a file named app.js in the project root:
console.log('Hello, Vizag!');
Step 3 — Run the Application
node app.js
Expected output:
Hello, Vizag!
That's it — JavaScript running entirely outside a browser, on bare metal.
Chapter 4: Understanding Modules
Node.js uses modules to encapsulate code. There are three kinds: core modules (built into Node.js), third-party modules (installed via NPM), and custom modules (files you write yourself).
Core Modules
Node.js ships with several built-in modules you can require() without installing anything:
fs— file system operations (read, write, delete files)http— create web servers and make HTTP requestspath— work safely with file and directory paths across operating systems
Using the http core module to create a web server:
const http = require('http');
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, Vizag!\n');
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}/`);
});
Run it:
node app.js
Navigate to http://localhost:3000/ in a browser — you'll see Hello, Vizag! served by pure Node.js with zero dependencies.
Third-Party Modules
Third-party modules are installed via NPM. express is the most widely used web framework for Node.js.
Install Express:
npm install express
This adds express to node_modules/ and records it in package.json under dependencies.
Create a simple Express server in app.js:
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello, Vizag!');
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}/`);
});
Run it:
node app.js
Navigating to http://localhost:3000/ now displays Hello, Vizag! — but this time routed through Express, which gives you a rich routing and middleware API to build on.
Custom Modules
Custom modules let you split code into separate files and require() them wherever needed.
Create greet.js:
module.exports = function(name) {
return `Hello, ${name}!`;
};
Use it in app.js:
const greet = require('./greet');
const name = 'Vizag';
console.log(greet(name));
Run it:
node app.js
Expected output:
Hello, Vizag!
module.exports is the public API surface of your file. Anything not attached to it stays private.
Chapter 5: Asynchronous Programming with Node.js
Node.js handles multiple operations without blocking the main thread through asynchronous patterns. There are three syntax styles for writing async code — callbacks, Promises, and async/await — and all three accomplish the same goal.
Callback Functions
Callbacks are functions passed as arguments and executed after an operation completes. They were Node.js's original async mechanism.
readFile.js — reading a file with a callback:
const fs = require('fs');
fs.readFile('example.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
node readFile.js
Expected output (assuming example.txt contains Hello, Vizag!):
Hello, Vizag!
The callback receives two arguments by convention: err first (null on success), then data. Always check err before using data.
Promises
Promises provide a cleaner way to handle async operations by chaining .then() and .catch() methods, avoiding deeply nested callbacks.
readFilePromise.js:
const fs = require('fs').promises;
fs.readFile('example.txt', 'utf8')
.then((data) => {
console.log(data);
})
.catch((err) => {
console.error(err);
});
node readFilePromise.js
require('fs').promises exposes the same filesystem methods wrapped in Promises instead of callbacks.
Async/Await
async/await syntax lets you write asynchronous code that reads synchronously, making complex flows much easier to follow and debug.
readFileAsync.js:
const fs = require('fs').promises;
async function readFile() {
try {
const data = await fs.readFile('example.txt', 'utf8');
console.log(data);
} catch (err) {
console.error(err);
}
}
readFile();
node readFileAsync.js
await pauses execution inside the async function until the Promise resolves, but critically it does not block the event loop — other callbacks continue to run while this function waits.
🧪 Try It Yourself
Task: Build a Node.js HTTP server that reads a text file and serves its contents as the response body.
- Create a file called
message.txtwith any content you like. - Create
server.jswith the following starter:
const http = require('http');
const fs = require('fs').promises;
const server = http.createServer(async (req, res) => {
try {
const content = await fs.readFile('message.txt', 'utf8');
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end(content);
} catch (err) {
res.statusCode = 500;
res.end('Could not read file.');
}
});
server.listen(4000, () => {
console.log('Server running at http://localhost:4000/');
});
- Run
node server.jsand openhttp://localhost:4000/in your browser.
Success criterion: The browser displays the exact text you wrote in message.txt. Edit the file and refresh — the server serves the updated content without restarting.
🔍 Checkpoint Quiz
Q1. Node.js is built on top of which JavaScript engine?
A) SpiderMonkey B) JavaScriptCore C) V8 D) Chakra
Q2. Given this code, what is printed to the console?
const greet = require('./greet');
console.log(greet('Vizag'));
Where greet.js is:
module.exports = function(name) {
return `Hello, ${name}!`;
};
A) greet('Vizag')
B) Hello, Vizag!
C) undefined
D) A ReferenceError
Q3. Which of these correctly reads a file using async/await in Node.js?
A) const data = fs.readFile('file.txt', 'utf8');
B) const data = await fs.readFile('file.txt', 'utf8'); inside an async function using fs.promises
C) const data = async fs.readFile('file.txt', 'utf8');
D) const data = Promise(fs.readFile('file.txt', 'utf8'));
Q4. Your app needs to serve a different HTML template for each incoming URL path. Which NPM package should you install to make routing manageable, and what command installs it?
A1. C — Node.js is built on Chrome's V8 engine, which compiles JavaScript to native machine code for fast execution.
A2. B — greet.js exports a function; calling it with 'Vizag' returns the interpolated string Hello, Vizag!, which console.log prints.
A3. B — await requires being inside an async function, and fs.promises.readFile (accessed via require('fs').promises) returns a Promise that await can unwrap into the file data.
A4. Install Express with npm install express. Express provides app.get('/path', handler) routing so each URL path maps to its own handler function, keeping your code organized.
🪞 Recap
- Node.js is a cross-platform JavaScript runtime built on Chrome's V8 engine, designed for scalable, server-side applications.
- NPM ships with Node.js and gives you access to hundreds of thousands of open-source packages with a single
npm installcommand. - Node.js modules come in three flavors: built-in core modules (
http,fs,path), third-party packages (likeexpress), and custom modules you export withmodule.exports. - Asynchronous I/O is the heart of Node.js — callbacks, Promises, and async/await are three syntax styles for writing non-blocking code that keeps the event loop free.
- A complete "Hello, Vizag!" server takes fewer than ten lines of JavaScript — the simplicity is intentional.
📚 Further Reading
- Official Node.js Docs — the source of truth on every built-in module, CLI flag, and release changelog
- NPM Registry — search every available package before writing something from scratch
- MDN — Promises — deep reference on the Promise API used throughout Node.js async code
- ⬅️ Previous: Introduction
- ➡️ Next: Introduction to phpMyAdmin