Every Node.js web framework, Express, Fastify, Koa, is ultimately built on top of the built-in http module. Understanding it directly demystifies what those frameworks are actually doing under the hood.
What Is the http Module?
http is a built-in module that lets you create HTTP servers and clients without any external dependency. http.createServer() takes a callback that runs for every incoming request, giving you a request object (req) and a response object (res) to read and reply with.
There's no routing, middleware, or body parsing built in, those are exactly the problems frameworks like Express solve. Working directly with http shows you what's happening underneath every higher-level abstraction.
import http from 'node:http';
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ message: 'Hello from Node.js!' }));
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000');
});
res.end() finishes the response, without calling it (or res.send() in Express), the client's connection will hang waiting for a reply.
req.method is the HTTP verb ('GET', 'POST', ...); req.url is the requested path plus query string.
res.setHeader() must be called before any data is written or the response is ended.
res.write() can be called multiple times to stream a response in chunks.
res.end() finishes the response, optionally accepting one final chunk of data.
http Module Cheatsheet
The core pieces of Node's raw HTTP server API.
Piece
Example
Purpose
Create server
http.createServer(handler)
Builds an HTTP server instance
Start listening
server.listen(3000)
Begins accepting connections on a port
Method
req.method
'GET', 'POST', 'PUT', 'DELETE', ...
URL
req.url
Path plus query string, e.g. /users?id=1
Status code
res.statusCode = 404
Sets the HTTP response status
Set header
res.setHeader('Content-Type', 'application/json')
Sets a response header
End response
res.end(body)
Sends the final response body and closes it
Reading a Request Body Manually
Unlike Express's req.body, the raw http module gives you the request body as a readable stream of binary chunks. You must manually collect and parse those chunks yourself, which is exactly the boilerplate that frameworks exist to remove.
const server = http.createServer((req, res) => {
let body = '';
req.on('data', (chunk) => {
body += chunk;
});
req.on('end', () => {
const data = JSON.parse(body || '{}');
res.end(JSON.stringify({ received: data }));
});
});
This manual pattern, listening for 'data' and 'end' events, is exactly what body-parsing middleware like express.json() automates for you.
Why Frameworks Build on Top of http
Once an app needs more than one or two routes, raw http quickly becomes repetitive: manually checking req.method/req.url for every route, parsing bodies by hand, and setting headers consistently. Frameworks like Express wrap http.createServer() internally and add routing, middleware, and convenience methods (res.json(), res.send()) on top.
Express's app object still ultimately calls http.createServer() under the hood.
req/res objects in Express are the same Node.js objects, extended with extra methods.
Learning raw http first makes Express (covered later in this course) far less "magic".
Common Mistakes
Forgetting to call res.end(), leaving client requests hanging indefinitely.
Setting headers after data has already been written, which throws an error.
Trying to read req.body directly, the raw http module has no such property, only a readable stream.
Not handling every possible req.url, causing unmatched routes to hang instead of returning a 404.
Key Takeaways
http.createServer() is the foundation every Node.js web framework builds on.
req and res are Node.js stream-based objects with no built-in routing or body parsing.
Request bodies must be manually collected from the 'data'/'end' stream events.
Frameworks like Express add convenience (routing, middleware, res.json()) on top of this same module.
Pro Tip
Build one tiny raw http server yourself before relying on Express. Seeing exactly how much boilerplate (manual routing, manual body parsing) a framework removes makes every Express concept click faster later in this course.
You've built a server with the raw http module. Next, learn the crypto module for hashing, encryption, and generating secure random values.