Node.js Cheatsheet

HTTP Server

Use this Node.js reference while you build software engineering projects, review code, or refresh the syntax you reach for most.

Creating an HTTP Server

import http from "node:http";

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

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

Request Object (IncomingMessage)

server.on("request", (req, res) => {
  req.method;          // "GET" | "POST" | "PUT" | "DELETE" ...
  req.url;             // "/path?a=1&b=2"  (raw, not parsed)
  req.headers;         // { host, "content-type", authorization, ... }
  req.headers["content-type"];
  req.httpVersion;     // "1.1"
  req.socket.remoteAddress;  // client IP

  // Parse URL
  const url = new URL(req.url, `http://${req.headers.host}`);
  url.pathname;        // "/path"
  url.searchParams.get("a");  // "1"
});

Response Object (ServerResponse)

// Status + headers (before any write)
res.statusCode = 200;
res.setHeader("Content-Type", "application/json");
res.setHeader("X-Custom", "value");
res.removeHeader("X-Powered-By");
res.getHeader("content-type");

// Combined (replaces any setHeader calls)
res.writeHead(201, {
  "Content-Type": "application/json",
  "Location": "/resource/1",
});

// Send body
res.write("chunk 1");   // partial body (can call many times)
res.write("chunk 2");
res.end();              // flush and close

res.end(JSON.stringify({ ok: true }));  // body + close in one call

// Check if headers already sent
res.headersSent;        // boolean

Reading the Request Body

// Raw chunks
async function readBody(req) {
  const chunks = [];
  for await (const chunk of req) {
    chunks.push(chunk);
  }
  return Buffer.concat(chunks).toString("utf8");
}

// JSON body
const body = JSON.parse(await readBody(req));

// With size limit
async function readBodyLimited(req, maxBytes = 1_000_000) {
  let size = 0;
  const chunks = [];
  for await (const chunk of req) {
    size += chunk.length;
    if (size > maxBytes) throw new Error("Payload too large");
    chunks.push(chunk);
  }
  return Buffer.concat(chunks).toString("utf8");
}

Routing by Hand

import http from "node:http";
import { URL } from "node:url";

const server = http.createServer(async (req, res) => {
  const url    = new URL(req.url, `http://${req.headers.host}`);
  const method = req.method;
  const path   = url.pathname;

  if (method === "GET"  && path === "/")          return handleHome(req, res);
  if (method === "GET"  && path === "/health")    return handleHealth(req, res);
  if (method === "POST" && path === "/echo")      return handleEcho(req, res);
  if (method === "GET"  && path.startsWith("/users/")) {
    const id = path.slice("/users/".length);
    return handleUser(req, res, id);
  }

  res.writeHead(404, { "Content-Type": "application/json" });
  res.end(JSON.stringify({ error: "Not found" }));
});

HTTPS Server

import https from "node:https";
import fs    from "node:fs";

const server = https.createServer({
  key:  fs.readFileSync("key.pem"),
  cert: fs.readFileSync("cert.pem"),
  // ca: fs.readFileSync("chain.pem"),  // optional CA bundle
}, (req, res) => {
  res.end("Secure!");
});

server.listen(443);

Making HTTP Requests (http.request / https.request)

import https from "node:https";

// Low-level
const req = https.request(
  "https://api.example.com/data",
  { method: "POST", headers: { "Content-Type": "application/json" } },
  (res) => {
    let body = "";
    res.setEncoding("utf8");
    res.on("data", chunk => body += chunk);
    res.on("end", () => console.log(JSON.parse(body)));
  }
);
req.on("error", console.error);
req.write(JSON.stringify({ hello: "world" }));
req.end();

For real projects use the built-in fetch (Node 18+) or a library.

fetch (Node 18+)

// GET
const res  = await fetch("https://api.example.com/items");
const data = await res.json();

// POST JSON
const res = await fetch("https://api.example.com/items", {
  method:  "POST",
  headers: { "Content-Type": "application/json", "Authorization": `Bearer ${token}` },
  body:    JSON.stringify({ name: "foo" }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const item = await res.json();

// Other response types
await res.text();         // string
await res.arrayBuffer();  // ArrayBuffer
await res.blob();         // Blob

// With timeout (AbortController)
const ac  = new AbortController();
const tid = setTimeout(() => ac.abort(), 5000);
const res = await fetch(url, { signal: ac.signal });
clearTimeout(tid);

// Inspect headers
res.headers.get("content-type");
res.status;       // 200
res.statusText;   // "OK"
res.url;          // final URL after redirects

Server Events

server.on("request", (req, res) => { ... });      // alias for callback
server.on("connection", (socket) => { ... });     // new TCP connection
server.on("close", () => console.log("closed"));  // server closed
server.on("error",  (err) => console.error(err)); // bind error etc.

// Graceful shutdown
process.on("SIGTERM", () => {
  server.close(() => {
    console.log("Server shut down");
    process.exit(0);
  });
});

Server Options

const server = http.createServer({
  keepAlive:          true,  // enable TCP keepalive
  keepAliveInitialDelay: 0,  // ms before first keepalive probe
  connectionsCheckingInterval: 30_000,
  requestTimeout:     300_000,  // ms to receive full request (Node 14.11+)
  headersTimeout:     60_000,   // ms to receive request headers
  maxHeaderSize:      16_384,   // bytes
});

server.timeout       = 120_000;   // ms — socket inactivity timeout
server.keepAliveTimeout = 5_000;  // ms — keep-alive idle timeout
server.maxHeadersCount = 2000;

HTTP/2 (h2)

import http2 from "node:http2";
import fs    from "node:fs";

const server = http2.createSecureServer({
  key:  fs.readFileSync("key.pem"),
  cert: fs.readFileSync("cert.pem"),
});

server.on("stream", (stream, headers) => {
  stream.respond({ ":status": 200, "content-type": "text/plain" });
  stream.end("Hello HTTP/2");
});

server.listen(443);