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

@rabbx/cluster

v1.0.0

Published

Edge-native, cross-platform clustering for modern JavaScript runtimes. Zero-downtime reloads. Backpressure. IPC. Structured logging. One API.

Downloads

141

Readme

@rabbx/cluster

Why @rabbx/cluster

Traditional clustering solutions are runtime-specific and lack modern features. @rabbx/cluster provides:

  1. True cross-platform - Same API across Node, Bun, Deno, Cloudflare Workers, and Vercel Edge
  2. Built-in observability - Health checks, Prometheus metrics, auto-restart
  3. Zero dependencies - 15KB gzipped, no supply chain risk
  4. Production hardened - Graceful shutdown, error recovery, hot reload
  5. Full WebSocket support - Integrated with @rabbx/ws for real-time apps
  6. KV integration - Built-in in-memory key-value store
  7. IPC support - Cross-process communication via native or KV channels

Installation

npm install @rabbxdev/cluster
yarn add @rabbxdev/cluster
pnpm add @rabbxdev/cluster
bun add @rabbxdev/cluster

Quick Start

import { createRabbxCluster } from '@rabbx/cluster';

const fetchHandler = (request) => {
  return new Response(JSON.stringify({ message: 'Hello World!' }), {
    headers: { 'Content-Type': 'application/json' }
  });
};

const { handler, workers, reload, shutdown, prometheus } = await createRabbxCluster(fetchHandler, {
  port: 8080,
  workerNums: 4
});

console.log('Server running on http://localhost:8080');
console.log('Health: http://localhost:8080/health');
console.log('Metrics: http://localhost:8080/metrics');

Platform Usage

Node.js

import { createRabbxCluster } from '@rabbx/cluster';

const fetchHandler = (request) => {
  return new Response(JSON.stringify({ message: 'Hello from node!' }), {
    headers: { 'Content-Type': 'application/json' }
  });
};

const { handler, workers, reload, shutdown } = await createRabbxCluster(fetchHandler, {
  host: 'localhost',
  port: 8080,
  workerNums: require('os').cpus().length,
  onError: (error) => console.error('Worker error:', error),
  onReady: () => console.log('Node cluster ready!')
});

// Handle graceful shutdown
process.on('SIGTERM', () => shutdown());
process.on('SIGINT', () => shutdown());
process.on('SIGUSR2', () => reload()); // Hot reload

Bun

import { createRabbxCluster } from '@rabbx/cluster';

const fetchHandler = (request) => {
  return new Response(JSON.stringify({ message: 'Hello from Bun!' }), {
    headers: { 'Content-Type': 'application/json' }
  });
};

const { handler, workers, reload, shutdown, kv } = await createRabbxCluster(fetchHandler, {
  port: 3000,
  workerNums: navigator.hardwareConcurrency || 4,
  onError: (error) => console.error('Bun error:', error),
  onReady: () => console.log('Bun cluster ready!')
});

// Bun-specific process management
process.on('SIGTERM', () => shutdown());
process.on('SIGUSR2', () => reload());

Deno

import { createRabbxCluster } from 'https://cdn.skypack.dev/@rabbxdev/cluster';

const fetchHandler = (request) => {
  return new Response(JSON.stringify({ message: 'Hello from Deno!' }), {
    headers: { 'Content-Type': 'application/json' }
  });
};

const { handler, reload, shutdown, kv } = await createRabbxCluster(fetchHandler, {
  port: 8000,
  onError: (error) => console.error('Deno error:', error)
});

Cloudflare Workers

import { createRabbxCluster } from '@rabbx/cluster';

const fetchHandler = async (request, env, ctx) => {
  return new Response(JSON.stringify({ 
    message: 'Hello from Cloudflare Workers!',
    region: env.CF_REGION 
  }), {
    headers: { 'Content-Type': 'application/json' }
  });
};

export default await createRabbxCluster(fetchHandler, {
  onError: (error) => console.error('Worker error:', error)
}).then(result => ({
  fetch: result.handler
}));

Vercel Edge Functions

// pages/api/edge.ts or app/api/edge/route.ts
import { createRabbxCluster } from '@rabbx/cluster';

const fetchHandler = async (request, env, ctx) => {
  return new Response(JSON.stringify({ 
    message: 'Hello from Vercel Edge!',
    geo: request.headers.get('x-vercel-ip-country')
  }), {
    headers: { 'Content-Type': 'application/json' }
  });
};

export default async (request) => {
  const { handler } = await createRabbxCluster(fetchHandler, {});
  
  return handler(request, {}, {});
};

WebSocket Integration

import { createRabbxCluster } from '@rabbx/cluster';
import { WebSocket } from '@rabbx/ws';

const fetchHandler = (request) => {
  return new Response('HTTP endpoint');
};

const { handler, websocket, kv } = await createRabbxCluster(fetchHandler, {
  port: 8080,
  wsOptions: {
    path: '/ws',
    maxPayload: 60 * 1024 // 60KB
  },
  setupWs: (wsServer) => {
    wsServer.addEventListener('connection', ({ detail: { socket } }) => {
      console.log('New WebSocket connection');
      
      socket.addEventListener('message', (event) => {
        // Process message and potentially store in KV
        kv.set(`msg:${Date.now()}`, event.data);
        socket.send(`Echo: ${event.data}`);
      });
      
      socket.addEventListener('close', () => {
        console.log('WebSocket disconnected');
      });
    });
  }
});

API Reference

createRabbxCluster(fetchHandler, options?)

Returns { handler, workers, isPrimary, server, reload, shutdown, prometheus, kv, websocket, ipc }

Options

| Option | Type | Description | |--------|------|-------------| | host | string | Hostname to bind to (default: 'localhost') | | port | number | Port to listen on (default: 8080) | | workerNums | number | Number of worker processes (default: CPU cores) | | setupServer | (server) => void | Hook to configure server after creation | | setupWs | (ws) => void | Hook to configure WebSocket server | | wsOptions | object | WebSocket configuration | | onError | (error) => void | Error handler | | onReady | () => void | Called when server is ready | | onWorkerExit | (code, signal) => void | Called when worker exits | | gracefulTimeout | number | Shutdown timeout in ms (default: 5000) |

Returns

| Property | Type | Description | |----------|------|-------------| | handler | Function | Request handler function | | workers | array | Worker instances (platform-specific) | | isPrimary | boolean | Whether current process is primary | | server | Server | Server instance (null in primary Node) | | reload | Function | Reload all workers | | shutdown | Function | Graceful shutdown | | prometheus | Function | Get Prometheus metrics string | | kv | KV | Key-value store instance | | websocket | WebSocketServer | WebSocket server instance | | ipc | IPCBus | Inter-process communication bus |

Built-in Endpoints

  • GET /health - Health check returning { status: 'ok', timestamp: '...' }
  • GET /metrics - Prometheus-formatted metrics

Production Features

Graceful Shutdown

process.on('SIGTERM', async () => {
  console.log('Gracefully shutting down...');
  await shutdown();
  process.exit(0);
});

Hot Reloading

// Unix/Linux: kill -USR2 <pid>
// Programmatic: await reload();
process.on('SIGUSR2', async () => {
  console.log('Hot reloading...');
  await reload();
});

Error Recovery

Workers automatically restart on unhandled errors. Configure with onError and onWorkerExit hooks.

Backpressure Handling

Automatic detection and response to high connection loads. Configurable threshold (default: 1000 connections).

Performance

  • Node.js: Up to 4x more concurrent connections than single-threaded
  • Bun: Native threading provides optimal performance
  • Deno: Efficient subprocess communication
  • Workers: Platform-managed scaling
  • Edge: Optimized for global distribution

Integration with @rabbx Ecosystem

FAQ

Does it work with TypeScript?

Yes, full TypeScript support with strict typing.

How does WebSocket clustering work?

Each worker can handle WebSocket connections independently. For shared state, use the integrated KV store.

Can I use it with existing frameworks?

Yes, integrates with Express, Fastify, Hono, Next.js, etc.

What about hot reloading in production?

SIGUSR2 triggers graceful reload with zero downtime.

License?

MIT - completely free to use.


Sponsors

@rabbx/cluster is MIT licensed and free forever. If it saves you server costs or dev time, consider sponsoring.

Why sponsor

  1. Fund development - More platforms, better error handling, advanced metrics
  2. Priority issues - Sponsors get responses within 24h
  3. Your logo here - $100+/mo gets your logo in README

Companies using @rabbx/cluster: Add your logo by sponsoring at the $100 tier.


Top Sponsors

Want to become a sponsor? Join here