~/
Building an HTTP Server
Quiz
...

Building an HTTP Server

intermediate · updated Tue Sep 22 2026Contribute

Create a web server with Node's built-in http module.

Building an HTTP Server

Node’s node:http module lets you build a web server with no dependencies. Frameworks like Express are built on top of it, so understanding it pays off.

A Minimal Server

import { createServer } from "node:http";

const server = createServer((req, res) => {
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.end("Hello from Node!");
});

server.listen(3000, () => {
  console.log("http://localhost:3000");
});

Run it, then open http://localhost:3000 in a browser.

The Request Object

req describes what the client asked for:

createServer((req, res) => {
  console.log(req.method); // "GET", "POST", ...
  console.log(req.url);    // "/about?x=1"
  console.log(req.headers); // { host, user-agent, ... }
});

Parse the URL and query string:

const url = new URL(req.url, "http://localhost");
console.log(url.pathname);            // "/about"
console.log(url.searchParams.get("x")); // "1"

The Response Object

res is how you answer:

res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ ok: true }));
  • writeHead(status, headers) sets the status and headers.
  • end(body) finishes the response.

Routing by Hand

createServer((req, res) => {
  const { pathname } = new URL(req.url, "http://localhost");

  if (req.method === "GET" && pathname === "/") {
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end("Home");
  } else {
    res.writeHead(404, { "Content-Type": "text/plain" });
    res.end("Not found");
  }
}).listen(3000);

This works, but it gets messy fast — that is why frameworks exist.

Reading a Request Body

Body data arrives as a stream:

let body = "";
for await (const chunk of req) {
  body += chunk;
}
const data = JSON.parse(body || "{}");

Best Practices

  1. Always set Content-Type — Browsers and clients depend on it.
  2. Send the right status code — 200, 201, 404, 500.
  3. Use a framework for real apps — Express or Fastify handle routing, parsing, and errors.
  4. Close responses — Every request needs an end() or it hangs.

Common Mistakes

  1. Forgetting res.end() — The request hangs forever.
  2. Parsing req.url as a full URL — It is a path; give new URL a base.
  3. Blocking the event loop — CPU-heavy work stalls every request.
  4. Ignoring the request methodGET /x and POST /x are different.