NodeJSThe http Module

The http Module

The http module is Node's built-in toolkit for the HTTP protocol — both serving requests (a web server) and making them (a client). It sits directly on top of the net/TCP layer: an HTTP server is a TCP server that parses the incoming byte stream into requests and formats responses back out. Everything from Express to Next.js ultimately runs on this module. Understanding it raw makes every framework feel like a thin convenience layer — because that's what they are.

What HTTP actually is

HTTP is a text-based request/response protocol over TCP. A client sends a request (method, path, headers, optional body); the server returns a response (status code, headers, optional body). The http module's job is parsing those bytes into JavaScript objects and serializing them back — so you work with req and res objects instead of raw text.

A raw HTTP/1.1 request and response (what flows over TCP)

Text
GET /users/42 HTTP/1.1          ← request line: method, path, version
Host: example.com               ← headers
Accept: application/json
                                ← blank line ends headers
                                ← (GET has no body)

HTTP/1.1 200 OK                 ← status line: version, code, reason
Content-Type: application/json  ← response headers
Content-Length: 27

{"id":42,"name":"Ada Lovelace"} ← response body
The smallest possible server

JS
import { createServer } from 'node:http'

const server = createServer((req, res) => {
  res.statusCode = 200
  res.setHeader('Content-Type', 'text/plain')
  res.end('Hello, World!\n')
})

server.listen(3000, () => console.log('http://localhost:3000'))
One handler runs for every request
`createServer(handler)` calls `handler(req, res)` for **each** incoming request. `req` is a readable stream (the [IncomingMessage](/nodejs/request-response)) carrying method, URL, headers, and body; `res` is a writable stream (the ServerResponse) you write the reply to. You *must* eventually call `res.end()` or the client hangs waiting. We dig into the server lifecycle in [Creating a Web Server](/nodejs/creating-server).
The pieces of the module

Export

Role

http.createServer([handler])

Create a server; handler gets (req, res)

http.request(options[, cb])

Make an outbound request (full control)

http.get(url[, cb])

Shorthand for a GET request

http.Server

The server class (an EventEmitter)

http.IncomingMessage

The req object — a readable stream

http.ServerResponse

The res object — a writable stream

http.Agent

Manages connection pooling / keep-alive

req and res are streams
The request body does NOT arrive with the request — you must read it
When your handler runs, only the **headers** have been received. `req` is a [readable stream](/nodejs/readable-streams); the body (for POST/PUT) streams in afterward. You have to consume it — via `for await`/`data` events — to get the payload. Forgetting this is the classic "why is req.body undefined?" beginner trap (Express hides it behind body-parser middleware, but raw Node does not).

JS
import { createServer } from 'node:http'

createServer(async (req, res) => {
  if (req.method === 'POST') {
    let body = ''
    for await (const chunk of req) body += chunk   // read the streamed body
    console.log('received:', body)
  }
  res.end('ok')
}).listen(3000)
`res` is a writable stream — you can pipe to it
Because the response is a writable stream, you can `pipe` a file or any readable straight to the client: `createReadStream('big.mp4').pipe(res)`. That streams the file with backpressure instead of buffering it in memory — the same streaming benefits from the [streams section](/nodejs/streams-intro), now over the network.
http vs https vs http2

Module

Use for

http

Plain HTTP/1.1 — dev, or behind a TLS-terminating proxy

https

HTTP over TLS — needs a certificate; see HTTPS Server

http2

HTTP/2 — multiplexing, server push (separate API)

In production, TLS is often terminated upstream
Many deployments run plain `http` in Node and let a reverse proxy (nginx, a load balancer, a cloud ingress) handle TLS. That's why `http` remains common in production code even though the public endpoint is HTTPS. When Node itself must serve TLS, use the `https` module with a key/cert.
A note on frameworks

You can build a whole app on raw http — and the next several pages do, deliberately, so you understand routing, headers, and bodies from first principles. But raw http has no routing, no body parsing, no middleware; you build all of it yourself. Frameworks like Express add those conveniences on top of this exact module. Learn the foundation here; reach for the framework when productivity matters.

Next
Build a real server: routing requests, sending responses, and the request lifecycle: [Creating a Web Server](/nodejs/creating-server).