You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reading the body out of the http.IncomingMessage is troublesome without any 3th party package...
Request on the other hand has features such as text, blob, json, arrayBuffer, formData bytes, and body for parsing it.
What is the feature you are proposing to solve the problem?
It would be a convenient to have something like a req.toWeb() utility added onto the simple http server 🚀
something like the stream.Readable.toWeb() but for the http.IncomingRequest to web Request
importhttpfrom'node:http'constapp=http.createServer(async(req,res)=>{constrequest=req.toWeb()awaitrequest.blob()awaitrequest.arrayBuffer()awaitrequest.bytes()awaitrequest.formData()awaitrequest.json()awaitrequest.body.pipeTo(dest)request.headers.has('content-length')// now getting the benefit of case insensitive.// full url (populated with host from request headers and http(s) based on using http or https)request.url// a abort signal that aborts when user cancel the request// can be useful for aborting other pending database queriesrequest.signal})
What alternatives have you considered?
currently doing some simplier variant like this one:
it's too verbose and having to do it in every project.
would have been nice to have that built in doe... there is also some signaling stuff, url construction and referrer that i would have to set up also to get a complete Request object.
i just thought this toWeb() would be better than having to add all of the other stuff Request has to make IncomingMessage be more web-like.
a alternative could be to have a getter function like:
classIncomingMessage{getrequest(){returnthis._request??=newRequest(...))}}// and then later be able to do something like:constapp=http.createServer(async(x,res)=>{constjson=awaitx.request.json()})
on another note it would also be nice to have a respondWith on the IncomingMessage as well so you can use respondWith a standardlized response object and combine it with the new fetch api and have it be very similar to a service worker and be able to have some isomorphic code shared between server and the browser.
classIncomingMessage{getrequest(){ ... }respondWith(x){ ... }}// and then later be able to do something like:constapp=http.createServer(asyncevt=>{constjson=awaitevt.request.json()evt.respondWith(fetch('https://httpbin.org/get'))})
Reacted by Endy Jasmi, David Brito, Jimmy Wärting, Dom Harrington, Dmitry Maganov, Merlin, Karim Jordan, aantthony, Ishiyama Yuzuki, Sơn Trần-Nguyễn and 6 more
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.
There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.
Reacted by Jimmy Wärting, Podaru Dragos, Jesse Pence, Jens Tschirpig, Ramrami Mohamed, Johan Lindkvist, Daniel Lenksjö, John L. Armstrong IV, Bruno Heridet, Gonçalo Alves and 1 more
I think it's clear that this is a highly requested feature many developer want judging by all 👍 and also the comments from bigger frameworks
Reacted by Moshe Brevda, Daniel Lenksjö, Federico Biccheddu, Marvin Hagemeister, Anders Pitman, kanad, Bruno Heridet, Simon Vadier, Kanashimia, Brian Kim and 4 more
I fail to see substantial benefit in converting Node's http.ClientRequest to web requests within the constraints of Node's http.Server RequestListener signature. This adds conversion overhead to every request.
However, it is the route that many userland server libs will take regardless to increase runtime compatibility (eg Nuxt's h3) and Node will have to address it somehow if its users are not to incur overhead on every request served in its runtime through a server lib/ framework with an ad-hoc impl.
Assuming Node's createServer(req:IncomingMessage, res:ServerResponse) RequestListener signature is too deeply embedded into Node to change breakingly, can the need to convert these request/ response representations be moved a layer down and be reduced by:
having a http.createWebServer with a WebRequestListener with a (req:Request, res:Response) type signature?
or have a useWeb option to the current http.createServer?
I don't think a clever trick can be pulled here to retrofit IncomingMessage onto Request as Node was able to do for Buffer on Uint8Array, as the new standard here is higher-level than Node's.
You're right on the performance aspect of the suggested feature. But there's another angle to it, which is about convenience. For this very common operations such as reading the body of a req (in various formats), you need to perform the data concatenation through various event listeners by hand or use stuffs like express' body-parser middleware which is yet another dependency. (which itself pulls other deps, like qs…)
the need to convert these request/ response representations be moved a layer down
Sure! The proposal you suggest about http.createWebServer with a WebRequestListener with a (req:Request, res:Response) definitely makes sense. (and this is akin to the API that Deno, CF Workers, Bun… already offer)
But I would say that it deserves its own GitHub issue, because its surface is broader, whereas the toWeb() proposed here feels like a lighter hanging fruit. In a sense the two approaches are complementary.
In their recent 2.0.0 release, Honojs (an Expressjs like framework) explained how they improve their Node.js adapter so that it keeps the same external API but has a more efficient story around the IncomingMessage => Request => app => Response => ServerResponse pipeline and body parsing.
I opened a separate issue for discussing a potential http.serve API#63096, so we can discuss the two topics independently.
I think this is an interesting topic overall. Although, I'm still a bit unsure about toWeb as it adds significant overhead and I'm not sure if it is practical enough. Maybe splitting the discussions will make it clearer where the actual demand is.
class IncomingMessage {
get request () { ... }
respondWith (x) { ... }
}
// and then later be able to do something like:
const app = http.createServer(async evt => {
const json = await evt.request.json()
evt.respondWith(fetch('https://httpbin.org/get'))
This issue has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
Reacted by Jesse Jackson, Eli, Jimmy Wärting, Federico Biccheddu and James Prevett
Sorry for taking a bit of a step back here, - I wasn't necessarily argueing Node.js needs a req.toWeb(), but that if it gets one, it doesn't add a lot of value in the context of the existing http.Server. The 'rather niche' examples from the following quote from the 'Beyond a subset' section from the 'Fetch is not enough' linked post in issue #63096:
The problem isn't just that server-side runtimes need fewer browser APIs. It's that they need capabilities the browser APIs were never designed to express. Informational responses, extended CONNECT, WebTransport sessions, datagram routing
.. make me wonder which of these cases are not appropriately (as in, impossible or too clunky) covered by existing (albeit lower-level?) Node.js http.* objects/methods? Also makes me question why the obviously-too-high-level Fetch browser standard was so eagerly adopted in server runtimes/ frameworks regardless of its known limitations: because it was the only standard? why were other "de facto standards" not considered for standardization - node's http being the server pioneer for JS?
VS XMLHttpRequest/ non-JS server runtimes, I never really came to terms with how JS fetch does not result in HTTP exceptions on responses with status codes higher than 3xx, unlike XMLHttpRequest/http.request's onerror handling - and you have to wrap the block in a try/catch anyway to get its text() or json() safely. I kind of get how response.ok can make sense in the browser context, but I find it very counterintuitive in a server runtime. No other server runtime requests lib I ever touched does not throw an http exception (php/ python/ java/ c#).
Also makes me question why the obviously-too-high-level Fetch browser standard was so eagerly adopted in server runtimes/ frameworks regardless of its known limitations: because it was the only standard? why were other "de facto standards" not considered for standardization - node's http being the server pioneer for JS?
I can take this one — it's true that Node is an alternative de facto standard. That was less true a few years ago, when a lot of these decisions were being made, and all the talk was about standards-based runtimes and WinterCG.
If you're a framework, there's a lot of value in being able to say 'here's how you use our primitives' without having to add '...on Node' and '...on Deno' and '...on Vercel' and '...on Cloudflare' and so on. You can just say, for example, that if you want to expose a POST handler you can do it like this...
...and if someone doesn't know what request.text() does you can point them at MDN. It's also a much nicer API than the closest node:http equivalent involving manually buffering chunks (or mucking about with a helper function that buffers chunks for you)!
Conceptually there's a very appealing simplicity to this approach — the handler is a(request: Request) => Response function. People are good at thinking in terms of those functions. Leaving aside the code gymnastics of the (req, res) => void approach: the idea that your code isn't returning a response, but is instead populating a response that was given to you, is just a lot more to get your head around. Frameworks tend to prioritise things like productivity and learnability very highly, whereas those who (justifiably!) lament the limitations of fetch are perhaps prioritising other things. (Take performance: obviously fetch has overhead. But it's very unlikely to be a real bottleneck in the vast majority of apps.)
In summary: all things considered, it was (and I would argue still is) the least worst option.
Activity
ronag commentedon Apr 2, 2022
Doesn't the alternative you propose already work?
jimmywarting commentedon Apr 2, 2022
it's too verbose and having to do it in every project.
would have been nice to have that built in doe... there is also some signaling stuff, url construction and referrer that i would have to set up also to get a complete Request object.
i just thought this
toWeb()would be better than having to add all of the other stuff Request has to make IncomingMessage be more web-like.a alternative could be to have a getter function like:
on another note it would also be nice to have a
respondWithon theIncomingMessageas well so you can userespondWitha standardlized response object and combine it with the new fetch api and have it be very similar to a service worker and be able to have some isomorphic code shared between server and the browser.github-actions commentedon Oct 18, 2022
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.
For more information on how the project manages feature requests, please consult the feature request management document.
github-actions commentedon Nov 18, 2022
There has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.
For more information on how the project manages feature requests, please consult the feature request management document.
ronag commentedon Jan 4, 2023
What about just introducing a new api? To avoid confusion and overlap, i.e.:
https://deno.land/manual@v1.28.3/examples/http_server#using-the-stdhttp-library
ronag commentedon Jan 4, 2023
I think the biggest challenge is implementing
req.34 remaining items
jimmywarting commentedon Oct 23, 2025
I think it's clear that this is a highly requested feature many developer want judging by all 👍 and also the comments from bigger frameworks
webketje commentedon Feb 17, 2026
I fail to see substantial benefit in converting Node's http.ClientRequest to web requests within the constraints of Node's http.Server RequestListener signature. This adds conversion overhead to every request.
However, it is the route that many userland server libs will take regardless to increase runtime compatibility (eg Nuxt's h3) and Node will have to address it somehow if its users are not to incur overhead on every request served in its runtime through a server lib/ framework with an ad-hoc impl.
Assuming Node's
createServer(req:IncomingMessage, res:ServerResponse)RequestListener signature is too deeply embedded into Node to change breakingly, can the need to convert these request/ response representations be moved a layer down and be reduced by:http.createWebServerwith aWebRequestListenerwith a(req:Request, res:Response)type signature?useWeboption to the currenthttp.createServer?I don't think a clever trick can be pulled here to retrofit IncomingMessage onto Request as Node was able to do for Buffer on Uint8Array, as the new standard here is higher-level than Node's.
Delapouite commentedon Feb 17, 2026
You're right on the performance aspect of the suggested feature. But there's another angle to it, which is about convenience. For this very common operations such as reading the body of a req (in various formats), you need to perform the data concatenation through various event listeners by hand or use stuffs like express'
body-parsermiddleware which is yet another dependency. (which itself pulls other deps, likeqs…)Sure! The proposal you suggest about
http.createWebServerwith aWebRequestListenerwith a(req:Request, res:Response)definitely makes sense. (and this is akin to the API that Deno, CF Workers, Bun… already offer)But I would say that it deserves its own GitHub issue, because its surface is broader, whereas the
toWeb()proposed here feels like a lighter hanging fruit. In a sense the two approaches are complementary.Delapouite commentedon Apr 21, 2026
In their recent 2.0.0 release, Honojs (an Expressjs like framework) explained how they improve their Node.js adapter so that it keeps the same external API but has a more efficient story around the
IncomingMessage => Request => app => Response => ServerResponsepipeline and body parsing.More details in these notes: https://github.com/honojs/node-server/releases/tag/v2.0.0
efekrskl commentedon May 3, 2026
I opened a separate issue for discussing a potential
http.serve API#63096, so we can discuss the two topics independently.I think this is an interesting topic overall. Although, I'm still a bit unsure about
toWebas it adds significant overhead and I'm not sure if it is practical enough. Maybe splitting the discussions will make it clearer where the actual demand is.ahmedmahmoud666 commentedon May 11, 2026
class IncomingMessage {
get request () { ... }
respondWith (x) { ... }
}
// and then later be able to do something like:
const app = http.createServer(async evt => {
const json = await evt.request.json()
evt.respondWith(fetch('https://httpbin.org/get'))
github-actions commentedon Aug 10, 2026
This issue has been marked as stale due to 90 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
Rich-Harris commentedon Aug 10, 2026
The relevance is undiminished by time. This issue is not stale
webketje commentedon Aug 10, 2026
Sorry for taking a bit of a step back here, - I wasn't necessarily argueing Node.js needs a
req.toWeb(), but that if it gets one, it doesn't add a lot of value in the context of the existinghttp.Server. The 'rather niche' examples from the following quote from the 'Beyond a subset' section from the 'Fetch is not enough' linked post in issue #63096:.. make me wonder which of these cases are not appropriately (as in, impossible or too clunky) covered by existing (albeit lower-level?) Node.js
http.*objects/methods? Also makes me question why the obviously-too-high-level Fetch browser standard was so eagerly adopted in server runtimes/ frameworks regardless of its known limitations: because it was the only standard? why were other "de facto standards" not considered for standardization - node's http being the server pioneer for JS?VS XMLHttpRequest/ non-JS server runtimes, I never really came to terms with how JS fetch does not result in HTTP exceptions on responses with status codes higher than 3xx, unlike XMLHttpRequest/http.request's onerror handling - and you have to wrap the block in a try/catch anyway to get its
text()orjson()safely. I kind of get howresponse.okcan make sense in the browser context, but I find it very counterintuitive in a server runtime. No other server runtime requests lib I ever touched does not throw an http exception (php/ python/ java/ c#).Rich-Harris commentedon Aug 11, 2026
I can take this one — it's true that Node is an alternative de facto standard. That was less true a few years ago, when a lot of these decisions were being made, and all the talk was about standards-based runtimes and WinterCG.
If you're a framework, there's a lot of value in being able to say 'here's how you use our primitives' without having to add '...on Node' and '...on Deno' and '...on Vercel' and '...on Cloudflare' and so on. You can just say, for example, that if you want to expose a
POSThandler you can do it like this......and if someone doesn't know what
request.text()does you can point them at MDN. It's also a much nicer API than the closestnode:httpequivalent involving manually buffering chunks (or mucking about with a helper function that buffers chunks for you)!Conceptually there's a very appealing simplicity to this approach — the handler is a
(request: Request) => Responsefunction. People are good at thinking in terms of those functions. Leaving aside the code gymnastics of the(req, res) => voidapproach: the idea that your code isn't returning a response, but is instead populating a response that was given to you, is just a lot more to get your head around. Frameworks tend to prioritise things like productivity and learnability very highly, whereas those who (justifiably!) lament the limitations offetchare perhaps prioritising other things. (Take performance: obviouslyfetchhas overhead. But it's very unlikely to be a real bottleneck in the vast majority of apps.)In summary: all things considered, it was (and I would argue still is) the least worst option.
anderspitman commentedon Aug 11, 2026
I enjoyed this article on the topic: https://blog.val.town/the-api-we-forgot-to-name