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

@whatwg-node/server

v0.9.55

Published

Fetch API compliant HTTP Server adapter

Downloads

1,840,954

Readme

WHATWG Node Generic Server Adapter

@whatwg-node/server helps you to create a generic server implementation by using WHATWG Fetch API for Node.js, AWS Lambda, Cloudflare Workers, Deno, Express, Fastify, Koa, Next.js and Sveltekit.

Once you create an adapter with createServerAdapter, you don't need to install any other platform specific package since the generic adapter will handle it automatically.

How to start

Let's create a basic Hello World server adapter.

// myServerAdapter.ts
import { createServerAdapter } from '@whatwg-node/server'

export default createServerAdapter((request: Request) => {
  return new Response(`Hello World!`, { status: 200 })
})

Integrations

You can use your server adapter with the following integrations:

Node.js

Node.js is the most popular server side JavaScript runtime.

import { createServer } from 'http'
import myServerAdapter from './myServerAdapter'

// You can create your Node server instance by using our adapter
const nodeServer = createServer(myServerAdapter)
// Then start listening on some port
nodeServer.listen(4000)

AWS Lambda

AWS Lambda is a serverless computing platform that makes it easy to build applications that run on the AWS cloud. Our adaoter is platform agnostic so they can fit together easily. In order to reduce the boilerplate we prefer to use Serverless Express from Vendia.

import { APIGatewayEvent, APIGatewayProxyResult, Context } from 'aws-lambda'
import type { Handler } from '@aws-cdk/aws-lambda'
import myServerAdapter from './myServerAdapter'

interface ServerContext {
  event: APIGatewayEvent
  lambdaContext: Context
}

export async function handler(
  event: APIGatewayEvent,
  lambdaContext: Context
): Promise<APIGatewayProxyResult> {
  const url = new URL(event.path, 'http://localhost')
  if (event.queryStringParameters != null) {
    for (const name in event.queryStringParameters) {
      const value = event.queryStringParameters[name]
      if (value != null) {
        url.searchParams.set(name, value)
      }
    }
  }

  const response = await myServerAdapter.fetch(
    url,
    {
      // For v1.0 you should use event.httpMethod
      method: event.requestContext.http.method,
      headers: event.headers as HeadersInit,
      body: event.body
        ? Buffer.from(event.body, event.isBase64Encoded ? 'base64' : 'utf8')
        : undefined
    },
    {
      event,
      lambdaContext
    }
  )

  const responseHeaders: Record<string, string> = {}

  response.headers.forEach((value, name) => {
    responseHeaders[name] = value
  })

  return {
    statusCode: response.status,
    headers: responseHeaders,
    body: await response.text(),
    isBase64Encoded: false
  }
}

Cloudflare Workers

Cloudflare Workers provides a serverless execution environment that allows you to create entirely new applications or augment existing ones without configuring or maintaining infrastructure. It uses Fetch API already so we can use our adapter as an event listener like below;

import myServerAdapter from './myServerAdapter'

self.addEventListener('fetch', myServerAdapter)

Deno

Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust. You can use our adapter as a Deno request handler like below;

import myServerAdapter from './myServerAdapter.ts'

Deno.serve(myServerAdapter)

Express

Express is the most popular web framework for Node.js. It is a minimalist framework that provides a robust set of features to handle HTTP on Node.js applications.

You can easily integrate your adapter into your Express application with a few lines of code.

import express from 'express'
import myServerAdapter from './myServerAdapter'

const app = express()

// Bind our adapter to `/mypath` endpoint
app.use('/mypath', myServerAdapter)

app.listen(4000, () => {
  console.log('Running the server at http://localhost:4000/mypath')
})

Fastify

Fastify is one of the popular HTTP server frameworks for Node.js.. You can use your adapter easily with Fastify.

So you can benefit from the powerful plugins of Fastify ecosystem. See the ecosystem

import fastify, { FastifyReply, FastifyRequest } from 'fastify'
import myServerAdapter from './myServerAdapter'

// This is the fastify instance you have created
const app = fastify({ logger: true })

/**
 * We pass the incoming HTTP request to our adapter
 * and handle the response using Fastify's `reply` API
 * Learn more about `reply` https://www.fastify.io/docs/latest/Reply/
 **/
app.route({
  url: '/mypath',
  method: ['GET', 'POST', 'OPTIONS'],
  handler: async (req, reply) => {
    const response = await myServerAdapter.handleNodeRequestAndResponse(req, reply, {
      req,
      reply
    })
    response.headers.forEach((value, key) => {
      reply.header(key, value)
    })

    reply.status(response.status)

    // Fastify doesn't accept `null` as a response body
    reply.send(response.body || undefined)

    return reply
  }
})

app.listen(4000)

Koa

Koa is another Node.js server framework designed by the team behind Express, which aims to be a smaller, more expressive. You can add your adapter to your Koa application with a few lines of code then benefit middlewares written for Koa.

import Koa from 'koa'
import myServerAdapter from './myServerAdapter'

const app = new Koa()

app.use(async ctx => {
  const response = await myServerAdapter.handleNodeRequest(ctx.req)

  // Set status code
  ctx.status = response.status

  // Set headers
  response.headers.forEach((value, key) => {
    ctx.append(key, value)
  })

  ctx.body = response.body
})

app.listen(4000, () => {
  console.log('Running the server at http://localhost:4000')
})

Next.js

Next.js is a web framework that allows you to build websites very quickly and our new server adapter can be integrated with Next.js easily as an API Route.

// pages/api/myEndpoint.ts
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'
import myServerAdapter from './myServerAdapter'

export const config = {
  api: {
    // Disable body parsing if you expect a request other than JSON
    bodyParser: false
  }
}

export default myServerAdapter

SvelteKit

SvelteKit is the fastest way to build svelte apps. It is very simple, and let you build frontend & backend in a single place

import myServerAdapter from './myServerAdapter'

export { myServerAdapter as get, myServerAdapter as post }

Bun

Bun is a modern JavaScript runtime like Node or Deno, and it supports Fetch API as a first class citizen. So the configuration is really simple like any other JS runtime;

import myServerAdapter from './myServerAdapter'

Bun.serve(myServerAdapter)

const server = Bun.serve(yoga)

console.info(`Server is running on ${server.hostname}`)

File Uploads / Multipart Requests

Multipart requests are a type of HTTP request that allows you to send blobs together with regular text data which has a mime-type multipart/form-data.

For example, if you send a multipart request from a browser with FormData, you can get the same FormData object in your request handler.

import { createServerAdapter } from '@whatwg-node/server'

const myServerAdapter = createServerAdapter(async request => {
  // Parse the request as `FormData`
  const formData = await request.formData()
  // Select the file
  const file = formData.get('file')
  // Process it as a string
  const fileTextContent = await file.text()
  // Select the other text parameter
  const regularTextData = formData.get('additionalStuff')
  // ...
  return Response.json({ message: 'ok' })
})

You can learn more about File API on MDN documentation.

Routing and Middlewares

We'd recommend to use fets to handle routing and middleware approach. It uses @whatwg-node/server under the hood.

Learn more about fets here