Express Intro & Routing
Express is the most popular web framework for Node.js — a thin layer over the http module that gives you a clean API for defining routes, handling requests, and sending responses with far less boilerplate.
Learn Express Intro & Routing in our free Node.js course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Node.js course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll have installed Express, written a server that responds to a request, defined routes for different HTTP methods and URLs, read route parameters and query strings, and sent back both plain text and JSON with the right status codes.
What You'll Learn in This Lesson
1️⃣ Installing Express & Your First Server
Express isn't built into Node — it lives on npm, the package registry. From inside your project folder you install it once, and it lands in node_modules so your code can require it.
Now the classic "hello server". Read every line below — it builds an app, defines one route, and starts listening. Save it as server.js and run node server.js .
2️⃣ Routing: Methods, Params & Queries
A route is the pairing of an HTTP method and a URL path with the function that handles it. Express gives you one method per verb — app.get , app.post , app.put , app.delete — and two ways to read variable data from the URL:
- • Route parameters — a segment starting with : like /users/:id is captured into req.params.id .
- • Query strings — the part after ? like /search?q=cats shows up parsed in req.query.q .
Your turn. The route below is almost done — fill in the two blanks marked ___ using the 👉 hints so a request to /ping returns JSON.
3️⃣ Sending Responses
The response object res is how you reply. The three you'll reach for constantly are res.send (text or HTML), res.json (data as JSON), and res.status (the HTTP status code, chained before a body). Each route may send exactly one response.
Mini-Challenge: A Tiny Greeting API
No blanks this time — just a brief and an outline. Write the two routes yourself, run the server, and check your output against the example in the comments. This is exactly the kind of small API that builds real fluency.
Common Errors (and the fix)
- "Cannot find module 'express'" — You forgot to install it, or you're in the wrong folder. Run npm install express inside your project (the one with package.json ) before running the file.
- Program exits immediately / nothing happens — You forgot app.listen(3000) . Without it the server is never started, so it has nothing to do and Node exits.
- "Cannot set headers after they are sent to the client" — You sent two responses in one handler (for example res.send(...) then res.json(...) ). Send exactly once, and return after sending so the rest of the handler doesn't run.
- req.params is undefined for your value — The key must match the route. /users/:id gives you req.params.id , not req.params.userId . The param name and the property name are the same word.
- A specific route never runs — Route order matters. A broad route like /users/:id declared first will shadow /users/new . Put literal, specific routes before parameterised ones.
Pro Tips
- 💡 Use res.json() for APIs: it sets the application/json header explicitly, making your intent clear to both clients and reviewers.
- 💡 Always return after sending: writing return res.status(404).json(...) prevents the dreaded "headers already sent" crash.
- 💡 Try a REST client like the browser, curl , or an extension to test POST/PUT/DELETE, which a browser address bar can't send on its own.
📋 Quick Reference — Express Basics
Concept
Express Syntax
Create the app
const app = express()
Define a GET route
app.get(path, fn)
Read a route param
req.params.id
Read a query value
req.query.q
Send text
res.send(x)
Send JSON
res.json(obj)
Set the status code
res.status(404)
Start the server
app.listen(3000)
Frequently Asked Questions
🎉 Lesson Complete!
- ✅ Express is a thin layer over http installed with npm install express
- ✅ const app = express() creates your server; app.listen(3000) starts it
- ✅ app.get/post/put/delete define routes per HTTP method
- ✅ req.params reads route params; req.query reads query strings
- ✅ res.send , res.json , and res.status shape the response — send exactly one
- ✅ Route order matters — put specific routes before parameterised ones
- ✅ Next lesson: Middleware
Practice quiz
What does calling express() return?
- A database connection
- An application object that is your whole server
- A single route handler
- The raw http module
Answer: An application object that is your whole server. express() creates the app object you attach routes to and start with app.listen().
Which method defines a handler for GET requests to a path?
- app.route()
- app.fetch()
- app.get()
- app.handle()
Answer: app.get(). app.get(path, handler) registers a handler for GET requests to that path.
A request to /users/42 hits app.get('/users/:id', ...). What is req.params.id?
- The string "42"
- The number 42
- undefined
Answer: The string "42". Route params arrive on req.params as strings, so req.params.id is "42".
Where does Express put parsed query-string values like ?q=cats?
- req.params
- req.body
- req.headers
- req.query
Answer: req.query. Query strings after the ? are parsed onto req.query, so req.query.q is "cats".
What does res.json() do that res.send() does not always do?
- It always sets the application/json header and serializes its argument to JSON
- It sends plain text only
- It closes the server
- It sets a 404 status
Answer: It always sets the application/json header and serializes its argument to JSON. res.json() always serializes to JSON and sets the JSON Content-Type explicitly.
How do you send a 404 status with a JSON error body?
- res.send(404)
- res.error(404)
- return res.status(404).json({ error: 'not found' })
- res.code(404).json(...)
Answer: return res.status(404).json({ error: 'not found' }). res.status(code) sets the HTTP status; chain .json() to send the body and return after sending.
What starts the server listening for connections?
- app.start(3000)
- app.run(3000)
- app.open(3000)
- app.listen(3000)
Answer: app.listen(3000). app.listen(3000, cb) binds the server to a port; without it Node has nothing to do and exits.
Why must /users/new be declared before /users/:id?
- Alphabetical order is required
- Express runs the first matching route, so :id would capture 'new' as the id
- Parameter routes are disabled otherwise
- It prevents a memory leak
Answer: Express runs the first matching route, so :id would capture 'new' as the id. Express matches top to bottom; a broad :id route declared first shadows the specific /users/new.
What causes 'Cannot set headers after they are sent to the client'?
- Forgetting app.listen
- Using app.get instead of app.post
- Reading req.query
- Sending two responses in one handler, e.g. res.send then res.json
Answer: Sending two responses in one handler, e.g. res.send then res.json. Each handler may send exactly one response; sending twice triggers the headers-already-sent error.
What is Express in relation to Node's http module?
- A thin framework layer on top of http with routing and helpers
- A replacement that removes http entirely
- A separate runtime like Node
- A database driver
Answer: A thin framework layer on top of http with routing and helpers. Express is a thin layer over http, adding routing, parsed params/query, and response helpers.
Continue this course
- Previous: Error Handling
- Next: Middleware