RFC 8297 103 Early Hints

RFC 8297 103 Early Hints — interim informational response the server sends BEFORE the final response, telling the browser which subresources it should start preloading while the server is still composing the final HTML / JSON. Browsers (Chrome 103+, Edge 103+, Firefox 120+) honor Link: rel=preload / rel=preconnect headers in the 103 to kick off resource fetches in parallel with the main render.

Operators reach for early-hints when the server has slow upstream dependencies (DB query, downstream API) but already knows the final response will reference specific CSS / JS / fonts / API origins. The 103 turns a single-RTT-bound page load into a parallel resource-prefetch chain.

b.earlyHints.send(res, { link, ... }) writes the interim 103 with the supplied headers. The framework wraps Node's built-in res.writeEarlyHints() (Node 18.11+) and adds:

- input validation (link entries must be RFC 8288 Link-header form: ; rel=preload[; as=script][; crossorigin=...]) - silent no-op when the operator-supplied res is not an HTTP/1.1+ socket-backed response (HTTP/1.0 clients don't understand 103; serializing one would corrupt the stream) - validation of cacheable header set per RFC 8297 section 3 (only headers that hint about the FINAL response are honored; Set-Cookie / authentication-related headers are refused)

The 103 does NOT replace the final response — the operator's handler still writes the regular 200/400/etc. status + body. Multiple 103s before the final response are permitted (Node's writeEarlyHints can be called repeatedly).

b.earlyHints.send(res, opts) #

stable0.8.88
{
  link:         string | string[],   // RFC 8288 Link-header values (REQUIRED)
}

Write an RFC 8297 103 Early Hints interim response to res. Returns true when the 103 was written, false when the underlying response does not support early hints (HTTP/1.0, a non-HTTP-shaped object, or the response writeEarlyHints API is missing).

link is either a single Link-header value string OR an array of strings. Each must follow the RFC 8288 Link-header grammar with a rel= parameter naming one of: preload, preconnect, prefetch, dns-prefetch, modulepreload, prerender, next, prev. Refused: per-link size > 4 KiB, missing rel=, unknown relation. Other operator-supplied header keys must NOT be in REFUSED_HEADERS (set-cookie / authorization / content-length / etc.) — those carry per-request state a 103 must not surface.

b.earlyHints.send(res, {
  link: [
    "; rel=preload; as=style",
    "; rel=preload; as=script",
    "; rel=preconnect",
  ],
});
res.statusCode = 200;
res.setHeader("Content-Type", "text/html");
res.end(html);

Last updated 2026-08-08T16:39:49.652Z by seeder.