Introduction
In lesson N.1 you built a server with Node's raw http module — and every visitor got the same answer, whatever they asked for. Real apps must answer differently by address: the home request gets one thing, the students list gets another, a wrong address gets an honest "not found". Doing that by hand means long chains of if checks on every request. Express is the package that removes that pain: it is a small framework on top of Node that gives you clean routes — one small function per address — and helpers that send text, HTML or JSON in one line.
Five lines of Express do what took a page of raw Node. That is why almost every Node backend in the world starts the same way you will in this lesson. (This lesson also covers the roadmap's 6.3 topic — your first API.) (Roman Urdu: Express server banana asaan kar deta hai — har address ke liye alag jawab, sirf chand lines mein.)
Key points
- Express is a package, not a new language:
npm install expressbrings it in; you load it withrequire("express")and call it once —const app = express()— to create your application. - A route is an address plus an answer:
app.get("/", handler)means "when a GET request arrives at/, run this function". The function receivesreq(the request) andres(the response). reqcarries what the visitor sent: the address, any values inside it, and any data posted.resis how you answer:res.send(...)for text or HTML,res.json(...)for data.res.jsonis the API answer: APIs do not send pages; they send JSON (lesson 3.18).res.json({ ... })turns your object into JSON and sends it with the right settings, automatically.(Roman Urdu: API ka jawab hamesha JSON hota hai —res.jsonwohi kaam ek line mein karta hai.)- Every route needs its own address:
/,/students,/about— Express matches the request's address to the route and runs only that one. app.listenopens the door: the same idea as raw Node — pick a port (3000 is the custom) and print a line so you know the server is awake.- A wrong address gets 404: if no route matches, Express answers "Cannot GET /..." — that honesty is built in; lesson N.9 will make it prettier.
Code examples
Example 1 — The five-line Express server
// server.js — run it with: node server.js
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.send("Welcome to my Express server!");
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});What it does: Three ideas in five lines. Load Express, create the app, and declare one route: a GET request to / (the home address) is answered with a line of text. app.listen then opens port 3000. Compare this with the raw http version from N.1 — no manual request checking at all.
What you will see: the terminal prints Server running on port 3000. Opening http://localhost:3000 shows Welcome to my Express server! — your first Express answer.
Example 2 — Different addresses, different answers
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.send("Home page");
});
app.get("/about", (req, res) => {
res.send("This app is built by a Code Scope student.");
});
app.get("/contact", (req, res) => {
res.send("Email: student@example.com");
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});What it does: Three routes, three addresses, three answers. Express reads the address of each incoming request and runs only the matching route's function — the if chain you would have written by hand in raw Node is simply gone. Adding a new page to the app is now just adding one more route.
What you will see: http://localhost:3000/ shows Home page, /about shows the about line, and /contact shows the email line. A fourth address, like /xyz, shows Express's built-in Cannot GET /xyz — proof that no route matched.
Example 3 — Your first API: answering with JSON
const express = require("express");
const app = express();
const students = [
{ id: 1, name: "Ali", marks: 70 },
{ id: 2, name: "Sara", marks: 92 },
{ id: 3, name: "Rahim", marks: 64 },
];
app.get("/students", (req, res) => {
res.json(students);
});
app.get("/students/count", (req, res) => {
res.json({ total: students.length });
});
app.listen(3000, () => {
console.log("API running on port 3000");
});What it does: This is the moment a "website" becomes an API. Instead of sending display text, the routes send data with res.json. The data lives in a normal JavaScript array of objects — the same arrays and objects from Series 3. Any app, website or phone can now ask this server for the students list and receive clean JSON it can use.
What you will see: http://localhost:3000/students shows the raw JSON of all three students in the browser, and /students/count shows {"total":3}. The browser displays it plainly because JSON is just text — a real frontend would read it with fetch, exactly like lesson 3.22.
Quick recap
- Express = the framework that turns raw Node servers into clean routes.
- One route per address:
app.get(address, (req, res) => { ... }). res.sendanswers text or HTML;res.jsonanswers data — that is an API.app.listen(3000)opens the door; unmatched addresses get an honest 404.
Common mistakes
- Forgetting to restart after every change — Node loads your file once; editing
server.jswhile it runs changes nothing on the port. The fix: Ctrl+C and runnode server.jsagain after each edit (later, tools like nodemon automate this). - Two routes, same address, confusion — if you declare
app.get("/")twice, only the first one ever runs; Express stops at the first match. The fix: one route per address and method; combine the answers inside it. - Answering data with
res.sendand a hand-built string — building JSON by joining text breaks the moment a name contains a quote. The fix: keep data in real objects and arrays, and always answer withres.json— it escapes and formats correctly for you.
Practice
- Build a server with three routes:
/sends your name,/citysends your city, and/hobbiesanswers withres.jsonand an array of three of your hobbies as objects like{ "hobby": "cricket" }. Test all three addresses in the browser. - Add a route
/students/topto the Example 3 API that answers with only the student who has the highest marks (use a loop orreducefrom lesson 3.11 to find them — do not hard-code the answer).