Skip to content

http: add experimental Fetch Server API prototype - #67447

Draft
jasnell wants to merge 6 commits into
nodejs:mainfrom
jasnell:jasnell/fetch-server-api
Draft

jasnell wants to merge 6 commits into
nodejs:mainfrom
jasnell:jasnell/fetch-server-api

Conversation

@jasnell

@jasnell jasnell commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Add an early prototype of the Fetch Server API proposal
(https://fetch-server.proposal.wintertc.org/), exposed as
http.fetchServer behind the new --experimental-http-serve flag.

The fundamental idea is a HTTP server API that is HTTP version agnostic and supports the full range of newer HTTP features like tunnels, unreliable datagrams, WebTransport (once QUIC/H3 are done), etc.

HTTP/3, QUIC, WebTransport, and HTTP/3 datagrams are not supported and
throw NotSupportedError. WebSocket upgrades are not implemented yet.

This has not yet been performance optimized and it's definitely slower than the current API.

Consider it a proof of concept.

Extremely experimental and very much in flux.

Some notes on the design:

  1. This is INTENTIONALLY not Node.js specific. That means no Node.js specific APIs surfaced through the API surface. The goal is for this to be implemented across multiple runtimes.
  2. This is also INTENTIONALLY not dependent on WHATWG fetch APIs. Those are too slow and we need to have options for optimizing that are not currently afforded by the WHATWG specs/process.

@nodejs/quic @nodejs/http @nodejs/http2 @mcollina

Add an early prototype of the WinterTC Fetch Server API proposal
(https://fetch-server.proposal.wintertc.org/), exposed as
`http.fetchServer` behind the new `--experimental-http-serve` flag.

This includes:

* `ServerResponse`, `ServerHeaders`, and `ServerRequest` with
  iterable-stream bodies, trailers, and cloning.
* The `ServerContext` and `ConnectContext` protocols, the exchange
  state model, informational responses, 100-continue handling,
  `deny()`, `waitUntil()`, and `completed`.
* The handler model, including the error() handler and fallbacks.
* `serve()`, `Server`, and `Listener`, built on the existing
  `node:http` and `node:http2` implementations, with HTTP/1.1, h2c
  (prior knowledge), and TLS with ALPN negotiation of h2.

HTTP/3, QUIC, WebTransport, and HTTP/3 datagrams are not supported and
throw NotSupportedError. WebSocket upgrades are not implemented yet.

Assisted-by: Claude Opus 5.5
Signed-off-by: James M Snell <jasnell@gmail.com>
Add tests for CONNECT, extended CONNECT, HTTP/1.1 upgrade
normalization, fall-through, and capsules over HTTP/2, and fix the
issues they found:

* Defer the RST_STREAM(NO_ERROR) that refuses an unread request body
  until the complete response has been sent, and only send it if the
  client has not already ended its side.
* Send `Content-Length: 0` for HTTP/1.1 responses without a body.

Assisted-by: Claude Opus 5.5
Signed-off-by: James M Snell <jasnell@gmail.com>
Implement `upgradeWebSocket()` and `upgradeWebSocketStream()` for
HTTP/1.1 upgrades and HTTP/2 extended CONNECT (RFC 8441), with:

* RFC 6455 framing: masking, fragmentation, ping/pong, the closing
  handshake, UTF-8 validation, and failing the connection on protocol
  violations.
* A server-side `WebSocket` with the WHATWG event API, whose close()
  accepts the close codes that a server can send.
* `ServerWebSocketStream`, whose readable and writable streams apply
  backpressure in both directions.
* Subprotocol selection by server preference, opt-in permessage-deflate
  (RFC 7692), `pingInterval`, and the `closeHandshake` and `tunnelIdle`
  timeouts.
* Close code 1001 on graceful server shutdown.

Assisted-by: Claude Opus 5.5
Signed-off-by: James M Snell <jasnell@gmail.com>
Add a self-contained "Fetch Server API" section to the `node:http`
documentation, covering `http.fetchServer.serve()`, the handler model,
`Server`, `Listener`, `ServerResponse`, the context and request
protocols, tunnels, WebSocket upgrades, protocol errors, and the
limitations of the prototype.

Assisted-by: Claude Opus 5.5
Signed-off-by: James M Snell <jasnell@gmail.com>
Add benchmarks for the fetch() handler of the experimental
`http.fetchServer` API over HTTP/1.1 and HTTP/2, each with and without
TLS. Let the HTTP/2 test double connect to servers with self-signed
certificates, as the HTTPS test double already does.

Assisted-by: Claude Opus 5.5
Signed-off-by: James M Snell <jasnell@gmail.com>
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/config
  • @nodejs/http
  • @nodejs/net
  • @nodejs/performance

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. config Issues and PRs related to Node.js configuration and feature settings. http Issues and PRs related to the http subsystem. needs-ci PRs that need a full CI run. labels Nov 12, 2026
Profiling showed that a response with a small body made two writes and
several promise races, and paid for request state that was not used.

* Send a body that is held as bytes, such as one from a string or a
  Uint8Array, with its Content-Length in a single write, instead of
  with chunked encoding in separate writes.
* Race exchange operations against an abort with a single promise that
  `abort()` rejects, instead of `SafePromiseRace()`. This also stops
  every race from adding a reaction to a promise that lives as long as
  the exchange.
* Hold the state of a context in a private field instead of a
  non-enumerable property.
* Build the HTTP/1.1 request header list lazily, without copying the
  hop-by-hop field set, and do not create the ServerRequest to check
  for HEAD.

Assisted-by: Claude Opus 5.5
@fry69

fry69 commented Nov 13, 2026

Copy link
Copy Markdown

Looks like https://fetch-server.proposal.wintertc.org/ is not yet online?

I found this link instead, if that helps -> https://proposal-fetch-server.jasnell.me/

Also this repo -> https://github.com/jasnell/proposal-fetch-server

@bnb

bnb commented Nov 13, 2026

Copy link
Copy Markdown
Member

this is sick, great work @jasnell

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. config Issues and PRs related to Node.js configuration and feature settings. http Issues and PRs related to the http subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants