npm.io
17.7.1 • Published yesterday

@jsenv/server

Licence
MIT
Version
17.7.1
Deps
0
Vulns
0
Weekly
0
Stars
36

server npm package

A Node.js HTTP server with declarative routing, content negotiation, file serving, WebSocket and Server-Sent Events.

import { startServer } from "@jsenv/server";

await startServer({
  port: 8080,
  routes: [
    {
      endpoint: "GET *",
      fetch: () => new Response("Hello world"),
    },
  ],
});

Features

  • Declarative routing: "GET /users/:id", the first route returning a response wins
  • 404, 405, 406, 415 and OPTIONS responses derived from the routes
  • Content negotiation for media type, language, version and encoding
  • File serving with etag/mtime client cache and compression
  • WebSocket and Server-Sent Events, with a broadcast helper
  • HTTPS, with http → https redirection; http2 as an option
  • CORS, server timing and error pages as plugins
  • Host header check (DNS rebinding) and bounded request bodies
  • A route inspector at /.internal/route_inspector

Installation

npm install @jsenv/server

Requires Node.js 22.13.1 or higher.

Quick examples

API server

import { startServer } from "@jsenv/server";

await startServer({
  port: 3000,
  routes: [
    {
      endpoint: "GET /api/users",
      fetch: () => Response.json([{ id: 1, name: "John" }]),
    },
    {
      endpoint: "GET /api/users/:id",
      fetch: (request) =>
        Response.json({ id: request.params.id, name: "John" }),
    },
    {
      endpoint: "POST /api/users",
      acceptedMediaTypes: ["application/json"],
      fetch: async (request) => {
        const user = await request.json();
        return Response.json(user, { status: 201 });
      },
    },
  ],
});

Static file server

import { createFileSystemFetch, startServer } from "@jsenv/server";

await startServer({
  routes: [
    {
      endpoint: "GET *",
      fetch: createFileSystemFetch(import.meta.resolve("./public/"), {
        etagEnabled: true,
        compressionEnabled: true,
      }),
    },
  ],
});

HTTPS server

import { readFileSync } from "node:fs";
import { startServer } from "@jsenv/server";

await startServer({
  https: {
    certificate: readFileSync(new URL("./server.crt", import.meta.url), "utf8"),
    privateKey: readFileSync(new URL("./server.key", import.meta.url), "utf8"),
  },
  routes: [
    {
      endpoint: "GET *",
      fetch: () => new Response("Welcome"),
    },
  ],
});

Documentation

Every option is described by the JSDoc of the export (startServer, createFileSystemFetch, serverPluginCORS, …): hover it in your editor. The pages below explain how the pieces fit together.

Topic Description
Handling requests Routes, the request object, the response formats
Handling errors What happens when a route throws, error pages
Plugins The hooks a server plugin can implement
Serving files Static files with client cache and compression
Content negotiation Media type, language, version and encoding negotiation
WebSocket Accepting WebSocket connections
Server-Sent Events Pushing events to clients
CORS Cross-Origin Resource Sharing
HTTPS HTTPS, http redirection and http2
Server timing Reporting where the server spent its time
Lifecycle Starting, stopping, keeping the process alive
Security What the server protects, what it leaves to you
Cluster One server per CPU core