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

@roomful/relay

v1.2.0

Published

Self-hosted relay server for Roomful realtime transports.

Readme

@roomful/relay

Self-hosted relay server for Roomful WebRTC signaling and WebSocket room transport.

Stable — v1.5. The API is stable and ready for production.

Install

Library usage:

npm install @roomful/relay

Global CLI usage:

npm install -g @roomful/relay

Run

CLI flags:

roomful-relay --port 8080
roomful-relay --host 0.0.0.0 --port 8787 --max-connections 1000
roomful-relay --max-room-size 50
roomful-relay --cors-origin https://app.example.com --auth-secret your-secret
roomful-relay --redis-url redis://127.0.0.1:6379/0   # experimental
roomful-relay --version

All flags take precedence over their matching environment variable.

| Flag | Environment variable | Description | | ---------------------------- | ----------------------- | -------------------------------------------------------- | | --port <number> | PORT / ROOMFUL_PORT | TCP port to listen on (default: 8787) | | --host <address> | HOST | Interface to bind (default: 127.0.0.1) | | --max-connections <number> | MAX_CONNECTIONS | Concurrent WebSocket connection cap | | --max-room-size <number> | ROOMFUL_MAX_ROOM_SIZE | Hard per-room peer cap | | --cors-origin <origin> | ROOMFUL_CORS_ORIGIN | Allowed browser origin (use * to allow any) | | --auth-secret <secret> | ROOMFUL_AUTH_SECRET | HS256 JWT secret enabling built-in authorization | | --redis-url <url> | ROOMFUL_REDIS_URL | Redis URL for multi-instance coordination (experimental) |

Environment variables:

| Variable | Default | Description | | -------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | PORT (or ROOMFUL_PORT) | 8787 | TCP port to listen on (ROOMFUL_PORT takes precedence over PORT) | | HOST | 127.0.0.1 | Interface to bind the relay server to | | MAX_CONNECTIONS | unset | Optional concurrent WebSocket connection cap | | ROOMFUL_MAX_ROOM_SIZE | unset | Hard per-room peer cap | | ROOMFUL_CORS_ORIGIN | unset | Allowed browser origin; adds CORS headers on HTTP responses and rejects WebSocket upgrades from other origins. Use * to allow any origin | | ROOMFUL_AUTH_SECRET | unset | Enables built-in HS256 JWT authorization; peers must present a valid token signed with this secret | | ROOMFUL_REDIS_URL | unset | Experimental. Optional Redis URL for multi-instance coordination; coordination semantics may change in a future release |

Health check:

curl http://127.0.0.1:8787/health

Docker

Published image — erayatesdev/roomful (:latest tracks the newest release; pin a version with :1.0.0):

docker pull erayatesdev/roomful:latest
docker run --rm -p 8787:8787 -e HOST=0.0.0.0 erayatesdev/roomful:latest

Local and production Compose examples live at the repository root in docker-compose.yml and docker-compose.prod.yml.

Powering the live demo

apps/demo (demo.roomful.dev) ships on BroadcastChannel by default — zero backend, multiplayer across tabs/windows in one browser. To upgrade it to cross-device multiplayer, deploy this relay and point the demo at it (no demo code change required):

  1. Deploy the relay (the erayatesdev/roomful image, the Compose files, or the roomful-relay CLI on Fly/Railway/Render). Set HOST=0.0.0.0 and ROOMFUL_CORS_ORIGIN=https://demo.roomful.dev.
  2. On the demo's Vercel project, set VITE_ROOMFUL_RELAY_URL=wss://your-relay-host and redeploy.

The demo auto-switches to the WebSocket transport whenever a relay URL is present. You can also test ad-hoc against any relay with ?relay=wss://your-relay-host appended to a demo URL.

A single relay instance needs no Redis, so the demo above runs Redis-free.

Scaling across instances (experimental)

Running multiple relay instances behind a load balancer requires Redis so peers landing on different instances can find each other. Point each instance at the same Redis with ROOMFUL_REDIS_URL (or --redis-url).

Experimental. Multi-instance Redis coordination is experimental and its semantics — for example, rejecting joins while Redis is unavailable — may change in a future release.

Edge (Cloudflare Workers)

The relay also runs on Cloudflare Workers + Durable Objects — no server to run, and no Redis. Cloudflare routes every connection for a room to one Durable Object instance, so a room's peers share a single in-memory object (the EdgeRoom engine) and coordinate without an external store.

Deploy with the included wrangler.jsonc (from a checkout of packages/relay, or the installed package directory):

npx wrangler deploy

Because routing happens at the WebSocket upgrade — before the join message is seen — the room id travels in the URL, so give each room its own relayUrl with a matching ?room=:

const roomId = 'doc-123';
createRoom(roomId, {
  transport: 'websocket',
  relayUrl: `wss://<worker-subdomain>.workers.dev/?room=${roomId}`,
});

The ?room= value must match the createRoom id (the engine rejects a mismatch).

Optional bindings:

  • RELAY_AUTH_SECRETwrangler secret put RELAY_AUTH_SECRET to require HS256 JWTs (verified with Web Crypto).
  • RELAY_MAX_ROOM_SIZE — a [vars] entry to cap peers per room.

The runtime-agnostic pieces (EdgeRoom, verifyRelayJwtEdge) are exported from the package root, so the same engine can back a Deno or other edge deployment.