Canonical monorepo for the Cloudflare relay Worker, reusable relay sidecar, shared relay protocol types, and local demo target app.
apps/relay-worker: Cloudflare Worker and Durable Object relay.apps/relay-client: reusable standalone Node sidecar that connects to/subscribeand forwards relayed HTTP requests to a target app.apps/demo-target: local HTTP app with a browser UI showing requests forwarded through the relay.packages/relay-protocol: shared WebSocket frame types, constants, and base64 helpers.
The deployed Cloudflare Worker is ensombl-relay-worker on the custom domain relay.dev.ensombl.io.
pnpm install
pnpm dev:demoDemo URLs:
- UI:
http://localhost:3000 - Worker:
http://localhost:8787 - Sidecar health:
http://localhost:8081/health
Send a request through the relay. The first path segment is the relay room and is stripped before forwarding to the target app:
curl -X POST 'http://localhost:8787/demo/webhook/hello?source=relay' \
-H 'Content-Type: text/plain' \
--data 'hello through relay'The request should appear in the demo UI.
The sidecar is configured by environment variables:
RELAY_BASE_URL: relay Worker WebSocket origin, for examplewss://relay.dev.ensombl.ioRELAY_ROOM: relay room, for exampleacmeRELAY_PATHS: comma- or newline-separated target path patterns, for example/webhooks/*,/auth/stripe/webhookTARGET_URLorRELAY_TARGET_URL: local app target URL, for examplehttp://host.docker.internal:3000TIMEOUT_MSorRELAY_TIMEOUT_MS: target request timeout, default15000RECONNECT_DELAY_MSorRELAY_RECONNECT_DELAY_MS: reconnect delay after relay disconnect, default1000HEALTH_PORTorRELAY_HEALTH_PORT: health server port, default8080LOG_LEVELorRELAY_LOG_LEVEL:trace,debug,info,warn,error, orfatal
The sidecar loads environment files in this order, with earlier values winning: RELAY_ENV_FILE, workspace root .env, then apps/relay-client/.env.
Build the sidecar image from the client directory as a standalone context:
docker build -t ensombl-relay-client apps/relay-clientpnpm typecheck
pnpm test
pnpm coverage
pnpm buildCoverage reports are written to each tested package's coverage/ directory, including:
apps/relay-worker/coverage/index.htmlapps/relay-client/coverage/index.html