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 🙏

© 2026 – Pkg Stats / Ryan Hefner

node-cluster-serve

v0.9.0

Published

Run a Node.js serve() function with optional node:cluster workers, graceful shutdown, and worker restart limits.

Downloads

57

Readme

node-cluster-serve

Run a Node.js serve function in single-process or node:cluster mode with graceful shutdown and worker restart limits.

  • Library: runServeFunction — you pass serve; the library does not load a file path.
  • CLI: node-cluster-serve resolves a module path, import()s it, and passes default as serve.

Install

npm install node-cluster-serve
# or
npx nypm add node-cluster-serve

Quick Start (CLI)

Your server module must default-export an async serve function. Return something with close (typically an http.Server) so SIGTERM/SIGINT can shut down gracefully.

serve receives a ServeContext: Omit<ServeOptions, 'serve'>. The runner sets defaults for mode, port, loggerPrefix, workerCount, and shutdown/restart fields. host may be undefined if nothing was passed and no local IPv4 was discovered (use a fallback when calling listen, as below).

// e.g. ./server.js (or ./server.ts if your Node/runtime can import TypeScript)
import { createServer } from 'node:http'
import type { ServeContext } from 'node-cluster-serve'

export default async function serve({ host, port }: ServeContext) {
  const httpServer = createServer((_req, res) => {
    res.end('ok\n')
  })

  await new Promise<void>((resolve, reject) => {
    httpServer.listen({ port, host: host ?? '0.0.0.0' }, (err) => (err ? reject(err) : resolve()))
  })

  return httpServer
}

Run it (use a path Node can import() — usually compiled .js, unless you rely on TypeScript stripping or a loader):

node-cluster-serve ./dist/server.js --mode production --port 3000 --workerCount 4

CLI Arguments

node-cluster-serve <serverModuleFile> [options]
  • serverModuleFile (positional, required): file path or file: URL to the server module.
  • --mode: development | production | test (default: NODE_ENV)
  • --host: bind host (default: HOST env, else first local IPv4)
  • --port: bind port (default: PORT env, else 3000)
  • --loggerPrefix: log prefix (default: [node-cluster-serve])
  • --workerCount: worker count (default: WORKER_COUNT or WEB_CONCURRENCY env, else 1)
  • --shutdownGraceMs: graceful shutdown timeout in ms (default: 10000)
  • --restartWindowMs: crash restart accounting window in ms (default: 30000)
  • --maxRestartsPerWindow: restart cap per window (default: 10)

The CLI resolves serverModuleFile to a file: URL and import()s it; default must be the serve function. Non-file: URLs (e.g. https:) are rejected.

Programmatic usage

Import serve yourself and pass it on options.serve.

import { runServeFunction } from 'node-cluster-serve'
import serve from './server.js'

await runServeFunction({
  serve,
  mode: 'production',
  host: '0.0.0.0',
  port: 3000,
  workerCount: 4,
  loggerPrefix: '[my-app]',
  shutdownGraceMs: 10_000,
  restartWindowMs: 30_000,
  maxRestartsPerWindow: 10,
})

When the promise resolves: it does not mean the process is about to exit — the HTTP server (or whatever you started) keeps the event loop alive.

  • Single worker (workerCount === 1): resolves after serve has resolved (e.g. after listen) and signal handlers are registered.
  • Cluster primary (workerCount > 1): resolves after workers are forked and the primary’s handlers are registered; each worker runs serve on its own.

Return value: runServeFunction fulfills with the ServeContext object passed into serve (same reference).

Cluster mode: forked workers start a new Node process and re-run your entry file. That entry should call runServeFunction again with the same serve (usually by importing a shared module) so each process has a real function reference.

Embedding the CLI

nodeClusterServeCommand is exported from node-cluster-serve for use with citty.

Serve function contract

type ServeFunction = (context: ServeContext) => Promise<ClosableServer | void>
type ServeContext = Omit<ServeOptions, 'serve'>

ClosableServer may be:

  • { close(callback) }, or
  • { close(): void | Promise<void> }, or
  • omitted (void) if you handle shutdown yourself.

The CLI expects a ServeModule: { default: ServeFunction }.

On SIGTERM/SIGINT, each worker awaits close() on the value returned from serve, then exits. The primary signals workers to shut down when using cluster mode.

Environment variables

  • NODE_ENV: fallback for mode
  • HOST: fallback for host
  • PORT: fallback for port
  • WORKER_COUNT / WEB_CONCURRENCY: fallback for workerCount when not set on the CLI or in options; if both are set, WORKER_COUNT wins

License

MIT