The Codex / JavaScript / http — HTTP Server

http — HTTP Server

Building HTTP servers in Node.js without frameworks — createServer, req/res objects, routing, status codes, and HTTPS.

What it is, in plain English: The http module (built into Node.js) lets you create HTTP servers from scratch. http.createServer() takes a callback that receives every request. The req object contains the method, URL, headers, and body. The res object sends the response — status code, headers, and body. This is what every web framework (Express, Fastify, Hono) wraps under the hood.

Your first HTTP server without a framework

Every web framework — Express, Fastify, Hono — sits on top of Node's built-in http module. Understanding the raw http module shows you what frameworks are actually doing.

The simplest possible server

import { createServer } from "http";

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

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

Reading the request

const server = createServer((req, res) => {
  console.log(req.method);   // "GET", "POST", "PUT", "DELETE" etc.
  console.log(req.url);      // "/api/users?page=2"
  console.log(req.headers);  // { "content-type": "application/json", ... }

  // Parse URL and query string:
  const url    = new URL(req.url, "http://localhost");
  console.log(url.pathname);         // "/api/users"
  console.log(url.searchParams.get("page")); // "2"
});

Sending responses

function sendJSON(res, statusCode, data) {
  res.writeHead(statusCode, {
    "Content-Type":                "application/json",
    "Access-Control-Allow-Origin": "*",   // CORS
  });
  res.end(JSON.stringify(data));
}

const server = createServer((req, res) => {
  if (req.method === "GET" && req.url === "/api/ping") {
    sendJSON(res, 200, { ok: true, ts: Date.now() });
    return;
  }
  sendJSON(res, 404, { error: "Not found" });
});

Reading the request body (POST/PUT)

// The body arrives as a stream — collect chunks:
function readBody(req) {
  return new Promise((resolve, reject) => {
    const chunks = [];
    req.on("data",  chunk => chunks.push(chunk));
    req.on("end",   ()    => resolve(Buffer.concat(chunks).toString()));
    req.on("error", reject);
  });
}

const server = createServer(async (req, res) => {
  if (req.method === "POST" && req.url === "/api/users") {
    try {
      const raw  = await readBody(req);
      const user = JSON.parse(raw);
      // ... save user ...
      sendJSON(res, 201, { ...user, id: Date.now() });
    } catch {
      sendJSON(res, 400, { error: "Invalid JSON body" });
    }
  }
});
Try It Yourself

Official Sources

The Codex links only to official documentation and the ECMAScript specification. No third-party tutorials.