~9 min read • Updated Dec 29, 2025
1. Introduction
The http2 module is accessed via require('node:http2'). It provides a low-level Core API for HTTP/2 features and a Compatibility API for easier migration from HTTP/1.
2. Server Example
const http2 = require('node:http2');
const fs = require('node:fs');
const server = http2.createSecureServer({
key: fs.readFileSync('localhost-privkey.pem'),
cert: fs.readFileSync('localhost-cert.pem'),
});
server.on('stream', (stream, headers) => {
stream.respond({ 'content-type': 'text/html; charset=utf-8', ':status': 200 });
stream.end('Hello World
');
});
server.listen(8443);
3. Client Example
const http2 = require('node:http2');
const fs = require('node:fs');
const client = http2.connect('https://localhost:8443', {
ca: fs.readFileSync('localhost-cert.pem'),
});
const req = client.request({ ':path': '/' });
req.on('response', (headers) => {
for (const name in headers) console.log(`${name}: ${headers[name]}`);
});
req.setEncoding('utf8');
let data = '';
req.on('data', (chunk) => { data += chunk; });
req.on('end', () => { console.log(data); client.close(); });
req.end();
4. Http2Session
Http2Session represents an active communication session between client and server. It manages settings, flow control, and multiplexed streams. Key events include:
- close: Fired when the session is destroyed.
- connect: Fired when the session connects to a peer.
- error: Fired on session errors.
- goaway: Fired when a GOAWAY frame is received.
- stream: Fired when a new
Http2Streamis created. - timeout: Fired when no activity occurs after a set timeout.
5. Http2Stream Lifecycle
Http2Stream instances represent bidirectional streams over a session. They are created when:
- Server receives a new HEADERS frame.
- Client calls
session.request(). - Server or client initiates a push stream.
Streams are destroyed when close(), destroy(), or RST_STREAM frames are used.
6. Advanced Features
- ALTSVC: Advertises alternative services (RFC 7838).
- ORIGIN: Advertises authoritative origins (RFC 8336).
- ping(): Sends a PING frame to measure latency.
- settings(): Updates local settings and waits for acknowledgment.
7. Example: Server Push
server.on('stream', (stream) => {
stream.respond({ ':status': 200 });
stream.pushStream({ ':path': '/style.css' }, (err, pushStream) => {
if (err) throw err;
pushStream.respond({ ':status': 200, 'content-type': 'text/css' });
pushStream.end('body { color: red; }');
});
stream.end('');
});
Conclusion
The http2 module in Node.js enables developers to build modern, efficient, and secure applications using HTTP/2 features such as multiplexed streams, server push, and advanced flow control. By leveraging Http2Session and Http2Stream, developers gain precise control over client-server communication.
1. Http2Stream Properties
aborted: Indicates abnormal termination of the stream.bufferSize: Number of characters currently buffered for writing.closed: True if the stream has been closed.destroyed: True if the stream has been destroyed and is no longer usable.endAfterHeaders: Indicates no additional data will be received after headers.id: Numeric identifier of the stream.pending: True if the stream has not yet been assigned an ID.rstCode: RST_STREAM error code when destroyed.
2. Header and Trailer Management
sentHeaders: Outbound headers sent for the stream.sentInfoHeaders: Additional informational headers sent.sentTrailers: Outbound trailers sent.sendTrailers(headers): Sends trailing headers after thewantTrailersevent.
3. Timeout and State Management
setTimeout(msecs, callback): Sets a timeout for the stream.state: Provides details such as window size and close status.
4. ClientHttp2Stream
The client variant of Http2Stream handles events such as:
- continue: Fired when a 100 Continue status is received.
- headers: Fired when informational headers are received.
- push: Fired when server push headers are received.
- response: Fired when the main response headers are received.
5. ServerHttp2Stream
The server variant of Http2Stream provides methods such as:
respond(headers[, options]): Initiates a response to the client.pushStream(headers[, options], callback): Creates a push stream to send additional data.respondWithFD(fd[, headers[, options]]): Sends response data from a file descriptor.respondWithFile(path[, headers[, options]]): Sends a file as the response.
6. Http2Server and Http2SecureServer
These classes manage HTTP/2 servers and provide events such as request, session, stream, and timeout. The secure variant (Http2SecureServer) uses TLS for encrypted communication.
7. Example
const http2 = require('node:http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond({ ':status': 200 });
stream.end('Hello from HTTP/2 stream');
});
server.listen(8000);
Conclusion
The Http2Stream class and its client/server variants in Node.js provide powerful tools for managing HTTP/2 streams. These features enable developers to build faster, more secure, and efficient applications with support for server push and direct file responses.
1. Key Events
- timeout: Fired when there is no activity on the server for a specified duration.
- unknownProtocol: Fired when a client fails to negotiate an allowed protocol (HTTP/2 or HTTP/1.1).
2. Server Management
server.close([callback]): Stops new sessions and gracefully shuts down the server.server.setTimeout([msecs][, callback]): Sets a timeout for server requests.server.timeout: Inactivity timeout before a socket is presumed closed.server.updateSettings([settings]): Updates server settings.
3. Creating an HTTP/2 Server
http2.createServer([options][, handler]): Creates an unencrypted HTTP/2 server.http2.createSecureServer(options[, handler]): Creates a secure HTTP/2 server using TLS.
4. Client Connections
http2.connect(authority[, options][, listener]) connects a client to an HTTP/2 server and returns a ClientHttp2Session instance.
5. Error Codes (http2.constants)
Error codes for RST_STREAM and GOAWAY frames include:
NGHTTP2_NO_ERROR: No error.NGHTTP2_PROTOCOL_ERROR: Protocol error.NGHTTP2_INTERNAL_ERROR: Internal error.NGHTTP2_FLOW_CONTROL_ERROR: Flow control error.NGHTTP2_CANCEL: Stream canceled.NGHTTP2_ENHANCE_YOUR_CALM: Error due to misbehaving client.
6. Header Management
- Headers are represented as key-value pairs in JavaScript objects.
- Header names are transmitted in lowercase.
- Sensitive headers (e.g., Cookie, Authorization) can be marked with
http2.sensitiveHeadersto avoid indexing in compression. - Raw headers format preserves ordering and duplicates for proxy use cases.
7. Example
const http2 = require('node:http2');
const fs = require('node:fs');
const options = {
key: fs.readFileSync('server-key.pem'),
cert: fs.readFileSync('server-cert.pem'),
};
const server = http2.createSecureServer(options);
server.on('stream', (stream, headers) => {
stream.respond({ 'content-type': 'text/html; charset=utf-8', ':status': 200 });
stream.end('Hello World
');
});
server.listen(8443);
Conclusion
Managing events and settings in HTTP/2 servers in Node.js allows developers to build secure, stable, and flexible servers. With methods like setTimeout and updateSettings, and events like timeout and unknownProtocol, developers gain precise control over the communication lifecycle.
1. Push Streams on the Client
To receive pushed streams on the client, set a listener for the stream event on ClientHttp2Session. These streams deliver additional data from the server without direct client requests.
2. Supporting the CONNECT Method
The CONNECT method allows an HTTP/2 server to act as a proxy for TCP/IP connections. The server validates CONNECT requests and establishes direct connections to the target. Clients can send CONNECT requests to the proxy to initiate tunneling.
3. Extended CONNECT Protocol (RFC 8441)
This protocol enables using CONNECT streams as tunnels for other communication protocols (e.g., WebSockets). Servers must enable enableConnectProtocol, and clients can then send CONNECT requests with the :protocol pseudo-header after receiving the SETTINGS frame.
4. Compatibility API
The Compatibility API provides an HTTP/1-like developer experience, allowing applications to support both HTTP/1 and HTTP/2. Classes Http2ServerRequest and Http2ServerResponse are designed for this purpose, though they do not hide protocol differences.
5. ALPN Negotiation
ALPN negotiation allows supporting both HTTPS and HTTP/2 over the same socket. With the allowHTTP1 option, servers can accept HTTP/1 requests alongside HTTP/2, enabling hybrid deployments.
6. Http2ServerRequest
This class represents incoming requests on an HTTP/2 server. Key properties include:
aborted: Indicates abnormal termination of the request.headers: Request headers object.httpVersion: HTTP version (typically 2.0).method: Request method (GET, POST, DELETE).url: Request path string.
7. Http2ServerResponse
This class represents outgoing responses from the server. Key methods and properties include:
addTrailers(headers): Adds trailing headers.appendHeader(name, value): Appends a new value to an existing header.createPushResponse(headers, callback): Creates a push response.end([data]): Ends the response.getHeader(name),getHeaders(): Retrieve headers.setHeader(name, value): Set a header.setTimeout(msecs, callback): Set a timeout for the response.
8. Example
const http2 = require('node:http2');
const server = http2.createServer((req, res) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.writeHead(200);
res.end('Hello from HTTP/2');
});
server.listen(8000);
Conclusion
HTTP/2 client and server features in Node.js provide powerful tools for managing push streams, CONNECT proxies, and compatibility with HTTP/1. These capabilities enable developers to build modern, secure, and flexible applications.
1. Core Properties
response.statusCode: Sets or reflects the status code when using implicit headers. After headers are sent, it shows the actual status code.response.statusMessage: Not supported in HTTP/2; always returns an empty string.response.stream: TheHttp2Streamobject backing the response.writableEnded: True afterend()has been called.
2. Sending Data
response.write(chunk[, encoding][, callback]): Sends part of the response body. IfwriteHead()has not been called, it switches to implicit header mode.- Can be called multiple times to send successive chunks of data.
- HEAD requests, and responses with status 204 or 304, must not include a body.
3. Special Methods
response.writeContinue(): Sends a 100 Continue status to indicate the request body should be sent.response.writeEarlyHints(hints): Sends a 103 Early Hints status with Link headers for resource preloading.response.writeHead(statusCode[, statusMessage][, headers]): Sends response headers with a status code. May be called only once beforeend().
4. Header Management
- Headers set with
setHeader()are merged with those passed towriteHead(), withwriteHead()taking precedence. Content-Lengthmust be specified in bytes. Node.js does not validate outbound body length against Content-Length, but inbound messages are validated.
5. Collecting Performance Metrics
The PerformanceObserver API can collect metrics for Http2Session and Http2Stream instances:
- For streams:
bytesRead,bytesWritten,id,timeToFirstByte,timeToFirstHeader. - For sessions:
framesReceived,framesSent,pingRTT,streamCount,maxConcurrentStreams.
6. Note on :authority and host
HTTP/2 requires either the :authority pseudo-header or the host header. Use :authority when constructing HTTP/2 requests directly, and host when converting from HTTP/1 (e.g., in proxies).
7. Example
const http2 = require('node:http2');
const server = http2.createServer((req, res) => {
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.writeHead(200);
res.write('Hello ');
res.end('World');
});
server.listen(8000);
Conclusion
The Http2ServerResponse class in Node.js provides powerful tools for managing HTTP/2 responses. With methods like writeHead, writeEarlyHints, and writeContinue, developers gain precise control over the response lifecycle, while the Performance Observer API enables monitoring of session and stream performance.
Written & researched by Dr. Shahin Siami