Skip to content

Is there a way to create a http server based on Fetch API? (Request, Response, Headers, ...) #4174

Closed as not planned

Description

@krutoo

Details

I want to create basic HTTP server with Node.js. I also want to declare request handler based on Fetch API like this:

import { serve } from 'node:http/nonexistent';

async function handler(request) {
  await doSomething();
  return new Response('{}', { headers: { 'content-type': 'application/json' } });
}

serve(handler, { port: 1234 });

Are there any built-in packages to achieve this?

If not, how to properly use the http package and convert IncomingMessage to Request and use the Response to send response in the handler of createServer function?

Node.js version

18+

Example code

Here is my naive implementation of the serve function. I have several quetions about it:

  • will such an implementation work fast enough? Or there are clear indicators of speed drawdown
  • can anyone suggest what use cases i'm missing (other than error handling)?
import { createServer } from 'node:http';
import { Readable } from 'node:stream';

export function serve({ port, fetch }) {
  const base = `http://localhost:${port}`;

  const server = createServer(async (req, res) => {
    const response = await fetch(
      new Request(new URL(req.url ?? '', base), {
        // body: ???
        headers: toHeaders(req.headers),
      }),
    );

    res.writeHead(response.status, [...response.headers]);

    if (response.body) {
      Readable.fromWeb(response.body).pipe(res);
    } else {
      res.end();
    }
  });

  server.listen(port);
}

function toHeaders(headers) {
  return Object.entries(headers).reduce((acc, [name, value]) => {
    if (typeof value === 'string') {
      acc.push([name, value]);
    } else if (Array.isArray(value)) {
      value.forEach(item => acc.push([name, item]));
    }

    return acc;
  }, []);
}

Operating system

macos

Scope

runtime

Module and version

Not applicable.

Activity

  1. preveen-stack commented on Jun 13, 2023

    @preveen-stack
    Contributor

    Can you show how the request looks like

  2. krutoo commented on Jun 13, 2023

    @krutoo
    Author

    @preveen-stack not quite understand what the request means?

  3. preveen-stack commented on Jun 13, 2023

    @preveen-stack
    Contributor

    If not, how to properly use the http package and convert IncomingMessage to Request and use the Response to send response in the handler of createServer function?
    the "Request" you mentioned in the issue

  4. krutoo commented on Jun 13, 2023

    @krutoo
    Author

    @preveen-stack global Node.js constructors Request and Response from Fetch API:

    new Request('http://site.com', { method: 'POST' });
    new Response('Not found', { status: 404 });
  5. jensmeindertsma commented on Oct 28, 2023

    @jensmeindertsma

    This seems like a pretty nice thing for Node.js to have. I'm trying to write these conversion methods myself but it's easy to mis something 😅 could this be a rework of createServer

  6. bra1nDump commented on Nov 8, 2023

    @bra1nDump

    Stumbled upon this while looking for solutions on how to use itty-router with node.js.
    Found this so far https://www.npmjs.com/package/@whatwg-node/server ... but it says it ponyfills, which is better than polyfilling, but it still does too much magic for my liking

  7. github-actions commented on May 7, 2024

    @github-actions

    It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment.
    If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
    Make sure to look at the README file for the most updated links.

  8. krutoo commented on May 7, 2024

    @krutoo
    Author

    @bra1nDump @whatwg-node/server is great, thanks

    But it looks like a little tricky solution and i dont think this is get great performance

  9. github-actions commented on Nov 28, 2024

    @github-actions

    It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment.
    If you need further assistance or have questions, you can also search for similar issues on Stack Overflow.
    Make sure to look at the README file for the most updated links.

  10. krutoo commented on Nov 28, 2024

    @krutoo
    Author

    Are there any plans to add builtin utilities for creating an HTTP server on Fetch API in Node.js?

  11. ydvkarthik commented on Dec 12, 2024

    @ydvkarthik
  12. avivkeller commented on Apr 7, 2025

    @avivkeller
    Member

    I'm closing this issue due to inactivity. At the current time, the only comments resolving the stalebot weren't relevant to resolving this issue, so I'll assume this is still stale.

    To answer the question, no, there is not currently a way to write a server via the Fetch API, although you can always implement one :-).

  13. mb21 commented on Sep 27, 2025

    @mb21

    Is this still not even under consideration? Nowadays, pretty much every JS-runtime except Node supports this: see https://blog.val.town/blog/the-api-we-forgot-to-name/ or https://marvinh.dev/blog/modern-way-to-write-javascript-servers/

  14. itsjavi commented on Jan 3, 2026

    @itsjavi

    It would be great for the ecosystem to (please) reconsider this, maybe under a standarized Fetch Server proposal together with WinterTC https://wintertc.org/

    Nowadays pretty much all modern frameworks and libraries use fetch-based APIs and objects (Request, Response, Headers, etc) and there is also a little overhead (from microseconds to a few ms depending on the implementation) when converting from Node's Req/Res to fetch and vice-versa:

    Incoming TCP socket
    → Node http.IncomingMessage / ServerResponse
    → Adapt to Fetch Request
    → (App logic)
    → Fetch Response
    → Adapt back to Node response
    → Socket write
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions