Devin Zuczek c9ec13fc6c update deps
2026-06-29 23:44:57 -04:00
2026-06-08 18:23:40 -04:00
2026-06-08 18:23:40 -04:00
2026-06-29 23:16:42 -04:00
2026-06-29 23:16:42 -04:00
2026-06-08 18:23:40 -04:00
2026-06-29 23:44:57 -04:00
2026-06-29 23:44:57 -04:00
2026-06-29 23:44:57 -04:00
2026-06-08 18:23:40 -04:00
2026-06-08 18:23:40 -04:00
2026-06-29 23:16:42 -04:00
2026-06-08 18:23:40 -04:00
2026-06-08 18:23:40 -04:00
2026-06-08 18:23:40 -04:00
2026-06-08 18:23:40 -04:00
2026-06-08 18:23:40 -04:00
2026-06-08 18:23:40 -04:00
2026-06-29 23:16:42 -04:00
2026-06-29 23:16:42 -04:00
2026-06-29 23:16:31 -04:00
2026-06-08 18:23:40 -04:00
2026-06-29 23:44:57 -04:00
2026-06-29 23:44:57 -04:00
2026-06-08 18:23:40 -04:00
2026-06-29 23:16:42 -04:00
2026-06-08 18:23:40 -04:00
2026-06-08 18:23:40 -04:00
2026-06-08 18:23:40 -04:00

RecFlare

RecFlare is an implementation of RecNet — the Rec Room backend — built on Cloudflare Workers. It implements the network services the Rec Room client talks to — accounts, auth, rooms, matchmaking, economy, chat, notifications, and more — each as an independent Worker on its own subdomain.

Disclaimer: This is an unofficial, fan-made project for preservation and experimentation. It is not affiliated with, endorsed by, or connected to Rec Room Inc. "Rec Room" is a trademark of its respective owner.

Client

RecFlare is compatible with the CannedNet client and the build of Rec Room with manifest 7859140924515540835. Other client or game versions expect different endpoints and response shapes and are not supported.

How it works

The Rec Room client discovers every service by fetching an endpoints document from the name-server (ns) worker at the apex domain. That document maps each service to a host like https://api.<your-domain>. Every service runs as a separate Cloudflare Worker attached to its own subdomain, so the client's traffic fans out across the workers in apps/.

Authentication is a Bearer-JWT flow: the auth worker issues tokens from /connect/token and owns the shared accounts table; every other worker validates that token on its auth-gated routes. New players are placed into the Orientation room on first login.

State is persisted with Cloudflare's storage primitives — D1 (SQLite) for accounts and rooms, KV for per-player settings and presence, R2 for images and CDN binaries, and a Durable Object for the real-time notifications hub. Endpoints that aren't backed by storage yet return sensible defaults and are marked TODO.

Services

These are every RecNet service the client discovers, taken from the service-discovery map in apps/ns/src/endpoints.ts. Each is reached at https://<subdomain>.<your-domain>. Services with a worker in apps/ are implemented here; the rest are advertised in the endpoints document but not yet backed by a Worker.

Service Subdomain Worker Notes
Accounts accounts accounts Player accounts & profile reads/writes (D1)
AI ai Not yet implemented
API api api Core Game API — config, social, avatar, rooms, image uploads (D1, R2)
Auth auth auth OAuth token issuance (/connect/token); owns the accounts table (D1, KV)
BugReporting bugreporting Not yet implemented
Cards cards Not yet implemented
CDN cdn cdn Binary CDN — signature blobs & room build data (R2)
Chat chat chat Chat service
Clubs clubs clubs Clubs
CMS cms Not yet implemented
Commerce commerce commerce Store / purchase endpoints
Data data Not yet implemented
DataCollection datacollection datacollection Client telemetry / analytics sink
Discovery discovery Not yet implemented
Econ econ econ Economy & avatar endpoints (separate from api)
GameLogs gamelogs Not yet implemented
Geo geo Not yet implemented
Images img img Image storage & signed delivery (R2)
Leaderboard leaderboard Not yet implemented
Link link Not yet implemented
Lists lists Not yet implemented
Matchmaking match match Matchmaking & per-player presence (D1, KV)
Moderation api api Served by the api worker (shares the API host)
Notifications notify notify Real-time notifications over SignalR/WebSockets (Durable Object)
PlatformNotifications platformnotifications Not yet implemented
PlayerSettings playersettings playersettings Per-player settings (KV)
RoomComments roomcomments Not yet implemented
RoomieIntegrations roomieintegrations Not yet implemented
Rooms rooms rooms Room storage & queries; seeds the Dorm & Orientation rooms (D1)
Storage storage Not yet implemented
Strings strings Not yet implemented
StringsCDN strings-cdn Not yet implemented
Studio studio Not yet implemented
Thorn thorn Not yet implemented
Videos videos Not yet implemented
WWW www Website host (not a Worker)

The ns worker itself serves this discovery document at the apex/ns host and isn't listed within it. Each implemented worker has its own README.md under apps/<name>/ documenting its routes.

Prerequisites

  • node.js v22 or later
  • pnpm v10 or later
  • bun 1.2 or later
  • A Cloudflare account with a zone (domain) you control, for deploying
  • shfmt / rg (ripgrep) — optional, recommended for shell formatting
  • mise — optional, recommended for tool management

Getting Started

Install dependencies:

just install

Configure your domain:

env.json is the single source of truth for your base domain; it is gitignored, so each clone needs its own copy.

cp env.example.json env.json
# edit env.json and set "domain" to your domain

just deploy reads env.json at deploy time and passes the base domain to wrangler — each worker is attached to its custom domain via --domain <subdomain>.<domain>, and the base domain is injected as the DOMAIN var so the ns service-discovery document and the api share-link base URL are built at runtime. Nothing in version control is rewritten; committed wrangler.jsonc files have no routes, and per-app subdomain overrides live under subdomains in env.json.

Run the development server:

just dev

Deploy all workers:

just deploy

Deploying requires wrangler to be authenticated against your Cloudflare account (wrangler login, or CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID in the environment). Storage resources (D1 databases, KV namespaces, R2 buckets) must be created and their ids set in each worker's wrangler.jsonc — see the inline comments in those files for the exact wrangler commands.

Repository Structure

  • apps/ - The service workers, one deployable Worker per subdirectory. Each has its own README.md, wrangler.jsonc, src/, and tests.
  • packages/ - Shared libraries and configuration used across the workers.
    • @repo/hono-helpers - Hono framework utilities (logging, error handling).
    • @repo/tools - The runx CLI and the bin/ scripts each worker's package.json delegates to, so build/test/deploy stays consistent.
    • @repo/typescript-config, @repo/oxlint-config - Shared TS and lint config.
  • turbo/generators/ - turbo gen templates for scaffolding new workers/packages.
  • Justfile - Convenient aliases for common development tasks.
  • pnpm-workspace.yaml - pnpm workspace definition.
  • turbo.jsonc - Turborepo task graph and caching.
  • .syncpackrc.cjs - Keeps dependency versions consistent across packages.

Available Commands

This repository uses a Justfile. Run just (or just --list) to see every command. Some key ones:

  • just install - Install all dependencies.
  • just dev - Start the dev server (context-aware: runs bun runx dev).
  • just build - Build all workers.
  • just test - Run tests (vitest).
  • just check - Check code quality: deps, lint, types, format.
  • just fix - Fix code issues: deps, lint, format, workers-types.
  • just deploy - Deploy all workers to your domain.
  • just new-worker (alias: just gen) - Scaffold a new service worker.
  • just new-package - Scaffold a new shared package.
  • just cs - Create a changeset for versioning.
  • just update deps - Update dependencies across the monorepo with syncpack.

For a single worker, scope with turbo, e.g. bun turbo -F api dev, bun turbo -F api test, or bun turbo -F api deploy.

Why a monorepo?

The services share types, auth logic, and tooling, so keeping them in one repo keeps those in sync: pnpm workspaces share dependencies, @repo/ packages share code, Turborepo runs build/test/lint with a single cached task graph, and cross-service changes land in one atomic commit.

S
Description
No description provided
Readme MIT 21 MiB
Languages
TypeScript 98.5%
CSS 0.6%
Shell 0.5%
Handlebars 0.3%