The HTTP and HTTPS modules

Reference for node:http and node:https in Cruft: the server half (createServer, IncomingMessage, ServerResponse) and the client half (request, get), which members are implemented, and the shared client limits such as no keep-alive and capped redirect following.

node:http is a focused module in Cruft's compatibility map: both halves ship, the server (createServer, streaming IncomingMessage, ServerResponse with writeHead/setHeader/write/end) and the client (http.request, http.get). The surface covers the request/response core; it stops short of full Node parity. node:https exposes the same client over a TLS 1.3 connection and a partial server adapter (createServer, Agent). Both, and the global fetch, are adapters over one canonical HTTP-client engine, so client behavior (redirect following, capped; AbortSignal honored) and limitations (no streaming request bodies, no keep-alive) are shared. All request and response callbacks are dispatched by the host event loop; a listening server keeps the process alive until closed.

Import forms

import http from 'node:http';
import https from 'node:https';
const http = require('node:http');   // bare 'http' / 'https' also resolve

API surface

Module-level

ExportNotes
http.createServer(handler)Returns a server; handler(req, res) runs per request.
http.request(url[, options][, cb])Returns a ClientRequest; cb(res) receives an IncomingMessage. Options include method, headers, body written via req.write.
http.get(url[, options][, cb])request plus an automatic .end().
http.AgentConstructor present; agents are inert placeholders (no connection pooling / keep-alive).
http.STATUS_CODESPartial code→reason-phrase table (common codes covered).
http.METHODSArray of HTTP method names (ACL, BIND, CHECKOUT, CONNECT, COPY, …).
https.request / https.getSame client over a TLS 1.3 connection.
https.createServerPartial TLS server adapter; do not assume full Node TLS server parity. (https.createSecureServer is not exported.)
https.AgentPresent; inert as with http.Agent.

Server and request/response objects

ObjectImplemented members
Serverlisten(port[, cb]), request listeners via createServer(handler) / on('request', …), close.
IncomingMessage (server request)method, url, headers; events data, end via on/once/addListener; resume, pause, setEncoding, pipe/unpipe, isPaused.
ServerResponsewriteHead(status[, headers]), setHeader, getHeader, removeHeader, hasHeader, getHeaderNames, write, end, flushHeaders, cork/uncork (no-ops), event registration (on, once, emit, listeners).
ClientRequestwrite, end, event registration (on, once, addListener, prependListener, removeListener), abort surface present.
IncomingMessage (client response)statusCode, headers; events data, end.

Examples

A request/response server; the body streams in via data/end:

import http from 'node:http';
const server = http.createServer((req, res) => {
  let body = '';
  req.on('data', (chunk) => { body += chunk; });
  req.on('end', () => {
    console.log(`${req.method} ${req.url} body=${JSON.stringify(body)}`);
    res.setHeader('X-Extra', 'yes');
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.write('hello ');
    res.end('world');
  });
});
server.listen(8431, () => console.log('listening'));
$ curl -s -i -X POST -d 'ping' http://127.0.0.1:8431/echo
HTTP/1.1 200 OK
x-extra: yes
content-type: text/plain
transfer-encoding: chunked

hello world

The client:

const http = require('node:http');
http.get('http://127.0.0.1:8800/hello', res => {
  let body = '';
  console.log(res.statusCode, res.headers['content-type']);
  res.on('data', c => body += c);
  res.on('end', () => console.log(body));
});
// → 200 application/json
// → {"method":"GET","path":"/hello"}

Write a request body with req.write(...) then req.end():

const req = http.request('http://127.0.0.1:8800/api', { method: 'POST' }, res => {
  let b = ''; res.on('data', c => b += c); res.on('end', () => console.log(b));
});
req.write('payload'); req.end();
// → {"method":"POST","got":"payload"}

STATUS_CODES and METHODS:

$ cruft -e 'import("node:http").then(m => {
  const h = m.default;
  console.log(h.STATUS_CODES[200], "/", h.STATUS_CODES[404], "/", h.STATUS_CODES[500]);
})'
OK / Not Found / Internal Server Error

Not implemented / gaps

Anything not listed above should be assumed absent. Known gaps:

  • Client: the client engine shared with fetch follows redirects (capped) and honors an AbortSignal (an aborted signal rejects with an AbortError); the same applies to node:http clients. There is no keep-alive or connection pooling yet, so an Agent is inert. Binary bodies are byte-faithful in both directions and client data chunks are real Buffers.
  • Server: no Upgrade/CONNECT handling, no trailers, no http.ClientRequest timeout controls, no server.setTimeout; cork/uncork/flushHeaders are accepted no-ops.
  • https server: partial adapter; TLS server machinery exists but Node server parity is not claimed.
  • STATUS_CODES is a partial table, not the full Node set.

Async behaviors (listeners, request delivery, client responses) run on the host event loop; ordering follows the loop's task scheduling, not Node's exact internal phase order.