fetch-to-node
Node.js-compatible request and response objects for WinterTC fetch-style runtimes
Repository Health
Technical Analysis
fetch-to-node bridges the gap between the WHATWG Fetch API and Node.js’s classic HTTP interface. It converts a Fetch Request into Node-style req and res objects and turns the written response back into a Fetch Response, so Node.js libraries that expect IncomingMessage/ServerResponse can run unchanged inside Cloudflare Workers, Bun, Deno, and Fastly Compute.
A fork of Fastly’s http-compute-js with dependencies stripped out and interfaces made runtime-agnostic, it depends only on a baseline level of Node compatibility (node:stream and node:buffer). This makes it a small, focused shim for reusing the vast Node HTTP ecosystem — Express included — on the modern edge.
What You Get
toReqRes(request)to convert a FetchRequestinto Node-compatiblereqandresobjectstoFetchResponse(res)to turn the written response back into a FetchResponsepromise- Faithful
IncomingMessageandServerResponseimplementations wired to the request body and an in-memory buffer - Zero runtime dependencies and full TypeScript typings out of the box
Common Use Cases
- Running Express or other Node HTTP middleware inside Cloudflare Workers
- Reusing Node-style request handlers on Bun, Deno, or Fastly Compute
- Porting an existing Node.js server to an edge runtime without rewriting handler code
Under The Hood
Architecture - The public surface in src/index.ts is deliberately thin: toReqRes and toFetchResponse from src/fetch-to-node/http-server.ts, plus the FetchIncomingMessage and FetchOutgoingMessage classes. toReqRes wires a Fetch Request body into a Readable-backed IncomingMessage, while the ServerResponse buffers writes in memory; toFetchResponse waits for the response’s finish event and assembles a Fetch Response from the accumulated status, headers, and body.
Tech Stack - Written entirely in TypeScript with zero runtime dependencies. The build is a plain tsc compile to ESM, and testing runs on Vitest. It relies only on Node’s node:stream and node:buffer primitives, which the target edge runtimes expose through their Node-compatibility layers.
Code Quality - The codebase is small, strictly typed, and organized into focused modules (http-incoming.ts, http-outgoing.ts, internal-streams-state.ts). A Vitest suite in http-server.test.ts exercises the round trip. Because it is a maintained fork of Fastly’s http-compute-js, it inherits a well-tested foundation. Known limitations (HTTP version always 1.1, no trailers, no client APIs) are documented honestly in the README.
API Design - Two functions cover the entire workflow, and their contracts mirror the Node HTTP objects developers already know, so existing handlers need no changes. The README documents parameters, return types, and edge cases clearly, keeping the boilerplate to a single conversion call at the boundary.