node:http — A Minimal HTTP Server
Node's built-in HTTP server module — request/response handling with no framework, and why every input from it is untrusted.
createServer((req, res) => {}).listen(port)
Purpose
node:http provides a low-level HTTP server with no framework layered on top — request routing,
body parsing, and similar are left to application code or a framework (Express and others) built on
this same module.
Syntax
import { createServer } from 'node:http';
const server = createServer((req, res) => {
if (req.url === '/health') {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('OK');
return;
}
res.writeHead(404);
res.end('Not found');
});
server.listen(3000);
Behavior notes
- The request body isn’t parsed automatically — it arrives as a readable stream (
req.on('data', …)/req.on('end', …), orfor await (const chunk of req)), and must be collected and parsed manually (or via a framework/middleware) for JSON or form data. req.url, headers, and the body are all client-supplied and must be treated as untrusted input — validated the same way any external input is, before being used to build a file path, database query, or any other sensitive operation.res.writeHead(status, headers)must be called beforeres.write()/res.end()— headers can’t be sent after the body has started.
Common mistakes
- Trusting
req.urlor header values without validation, opening the door to path traversal or injection if that data flows into a file path, command, or query unmodified. - Forgetting to call
res.end(), leaving a request hanging indefinitely with no response sent.
Runtime notes
Node-specific — a browser has no equivalent, since a browser is an HTTP client, not typically a server.