npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@mjackson/node-fetch-server

v0.5.0

Published

Build servers for Node.js using the web fetch API

Downloads

163,083

Readme

node-fetch-server

node-fetch-server allows you to build servers for Node.js that use the web Fetch API primitives (namely Request and Response) instead of the traditional req/res API used in libraries like Express.

This web standard API is already used in many places across the JavaScript ecosystem:

When you write servers using the Request and Response APIs, you maximize the chances that your code will be portable across these different JavaScript runtimes.

Features

  • Use web standard Request and Response APIs for building servers, instead of node-specific API
  • Seamless integration with node:http and node:https modules
  • Supports custom hostnames (e.g. using process.env.HOST on a VPS to set the host portion of incoming request URLs)
  • Supports streaming responses using new Response(stream)
  • Exposes remote client address info

Installation

npm install @mjackson/node-fetch-server

Usage

import * as http from 'node:http';
import { createRequestListener } from '@mjackson/node-fetch-server';

function handler(request: Request) {
  return new Response('Hello, world!');
}

let server = http.createServer(createRequestListener(handler));

server.listen(3000);

By default request.url is derived from the value of the Host HTTP header and the connection protocol being used. To support custom hostnames using e.g. a HOST environment variable, you can use the host option:

import * as assert from 'node:assert/strict';
import * as http from 'node:http';
import { createRequestListener } from '@mjackson/node-fetch-server';

function handler(request: Request) {
  // This is now true
  assert.equal(new URL(request.url).host, process.env.HOST);
  return new Response('Hello, world!');
}

let server = http.createServer(createRequestListener(handler, { host: process.env.HOST }));

server.listen(3000);

Information about the remote client IP and port is passed as the 2nd argument to your FetchHandler:

import { type FetchHandler } from '@mjackson/node-fetch-server';

let handler: FetchHandler = (request, client) => {
  return new Response(`The client IP address is ${client.address}`);
};

Low-level API

In addition to the high-level createRequestListener() API, this package also provides 2 low-level APIs that are useful when building custom fetch-based servers in Node.js:

  • createRequest(req: http.IncomingMessage, res: http.ServerResponse, options: RequestOptions): Request
  • sendResponse(res: http.ServerResponse, response: Response): Promise<void>

These two functions serve as an efficient, minimal translation layer between Node.js req/res objects and fetch Request/Response objects. You could build your own custom server like this:

import * as http from 'node:http';
import { createRequest, sendResponse } from '@mjackson/node-fetch-server';

let server = http.createServer(async (req, res) => {
  let request = createRequest(req, res, { host: process.env.HOST });

  try {
    let response = await customAppLogic(request);
    await sendResponse(res, response);
  } catch (error) {
    console.error(error);
    res.writeHead(500, { 'Content-Type': 'text/plain' });
    res.end('Internal Server Error');
  }
});

server.listen(3000);

Related Packages

  • fetch-proxy - Build HTTP proxy servers using the web fetch API

Benchmark

A basic "hello world" benchmark shows node-fetch-server introduces considerable overhead on top of a vanilla node:http server. However, it is still able to serve more requests per second (and has higher overall throughput) than Express v4, so the slowdown should be acceptable for most applications.

> @mjackson/[email protected] bench /Users/michael/Projects/remix-the-web/packages/node-fetch-server
> bash ./bench/runner.sh

Platform: Darwin (24.0.0)
CPU: Apple M1 Pro
Date: 11/14/2024, 2:30:22 PM

Running benchmark for node:[email protected] ...

Running 30s test @ http://127.0.0.1:3000/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     9.97ms   31.92ms 786.67ms   99.09%
    Req/Sec     4.45k   268.33     6.38k    93.69%
  1594257 requests in 30.02s, 326.89MB read
  Socket errors: connect 0, read 1317, write 6, timeout 0
Requests/sec:  53110.92
Transfer/sec:     10.89MB

Running benchmark for [email protected] ...

Running 30s test @ http://127.0.0.1:3000/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    22.74ms   81.06ms   1.46s    98.22%
    Req/Sec     2.42k   185.82     4.30k    91.80%
  866347 requests in 30.03s, 177.64MB read
  Socket errors: connect 0, read 1496, write 3, timeout 0
Requests/sec:  28849.46
Transfer/sec:      5.92MB

Running benchmark for [email protected] ...

Running 30s test @ http://127.0.0.1:3000/
  12 threads and 400 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    36.46ms  125.89ms   1.99s    97.89%
    Req/Sec     1.56k   146.86     2.93k    88.25%
  558504 requests in 30.06s, 134.76MB read
  Socket errors: connect 0, read 1261, write 11, timeout 36
Requests/sec:  18579.11
Transfer/sec:      4.48MB

License

See LICENSE