webwire
@johnhenry/webwire converts between Node’s raw http/https objects
(IncomingMessage, ServerResponse, http.request()) and the Web Fetch API
(Request, Response). Four small functions, no dependencies, no build step.
Node’s HTTP API predates Fetch and does not speak it. Code that works in
Request/Response terms (a router, a proxy, a test harness) still has to touch
Node’s sockets in exactly four places, and this package is those four places and
nothing else:
| You have | You want | Function |
|---|---|---|
A server-side IncomingMessage |
A Web Request |
toWebRequest() |
A Web Response |
Bytes written to a ServerResponse |
writeWebResponse() |
A Request (or a URL) |
Options for http.request() |
toNodeRequestOptions() |
A client-side IncomingMessage |
A Web Response |
toWebResponse() |
A fifth pair, setTrailers() / getTrailers(),
lets a Response carry HTTP trailers, which Fetch has no way to express.
Install
Section titled “Install”npm install @johnhenry/webwireRequires Node 26 or newer (engines.node is >=26.0.0). Types ship in the
package (index.d.ts). See Getting started.
The pages here
Section titled “The pages here”- Getting started: install, a server that answers with a
Response, an outbound call that returns one - API: every export, with signatures, options, return values and errors
- Serving:
IncomingMessagein,Responseout; reverse-proxy hosts, streaming, cookies, trailers, WebSocket upgrades - Calling out:
Requestin,http.request()options out,Responseback; buffered and streamed bodies, proxying - Limitations and traps: what fails quietly, traps first
What it deliberately is not
Section titled “What it deliberately is not”It does not route, parse bodies, or make requests. toNodeRequestOptions()
returns plain data and leaves issuing the request to you, and toWebResponse()
does not read the response it is given. If you want a server built on this
conversion, see leserve.
Family
Section titled “Family”webwire was extracted from the code its siblings had each grown a copy of. Some depend on it; the others share a theme.
- leserve: a
serve()that takes a plain(Request) => Responsehandler. Its published0.1.0has a hard dependency on@johnhenry/webwire;serve()usestoWebRequest()andwriteWebResponse(), and leserve keeps the oldleserve/node-requestandleserve/node-to-websubpaths as re-exports oftoWebRequest()andtoWebResponse(). - servant: depends on leserve, for
toWebRequest()vialeserve/node-request, so it reaches webwire only transitively. That dependency is the evidence the conversion was useful apart from running a server. - dialback: its
Serverhad reimplemented both server-side conversions. The dialback repository’smainnow declares@johnhenry/webwireas a dependency; the published0.0.3does not. - prism: an HTTP inspector whose
timed-fetch.mjscallstoNodeRequestOptions()for connection details and keeps its own socket-timing hooks. Itsmaindeclares the dependency; it has no docs section here and is not on npm. - http-converter and http-fields: no
dependency in either direction; neighbours by topic only. http-converter turns HTTP
text formats (raw HTTP, HAR, cURL) into
Request/Response; webwire connects those objects to Node’s sockets. http-fields parses the structured values inside headers.
License
Section titled “License”MIT