Case Study
Custom Streaming Overlays – Real-Time Event Platform (Kick & StreamElements)
A full-stack real-time overlay platform built around a custom Node.js WebSocket server.
The system aggregates live events from Kick and StreamElements, normalizes them, and pushes them to browser-based overlays used directly in OBS.
The entire project is structured as a TypeScript monorepo with a shared contract layer.
Project Scope
The platform focuses exclusively on real-time delivery. No persistence, no dashboards, and no historical data — only low-latency event flow from streaming platforms to on-screen overlays.
Contents
1. Motivation & Scope
The goal of this project was to build a single, controllable entry point for real-time streaming events and expose them to browser-based overlays without relying on third-party realtime services.
- Aggregate events from multiple external providers.
- Normalize different event formats into a single internal model.
- Push events to overlays with minimal latency.
- Keep the system stateless and simple to operate.
2. Monorepo Architecture
The project is implemented as a TypeScript monorepo using PNPM workspaces. This allows the server and overlays to share a strict, versioned contract without duplicating logic or types.
Server
- Node.js + Express.
- HTTP endpoints for webhooks and OAuth.
- WebSocket server for real-time delivery.
- Stateless runtime.
Shared Package
- Strongly typed event contracts.
- Shared constants (ports, channel names).
- Used by server, overlays, and scripts.
Overlays
- Vite + TypeScript.
- Frameworkless by design.
- Optimized for OBS browser sources.
3. High-Level System Architecture
A single Node.js server acts as the central aggregation point for all incoming events and outgoing WebSocket traffic. Overlays connect directly to this server and listen for normalized events.
4. Event Pipeline & Flow
- Kick events are received via signed webhooks.
- Kick chat messages are consumed via a persistent WebSocket connection.
- StreamElements alerts are verified and mapped into internal event types.
- All valid events are broadcast immediately to connected overlays.
5. WebSocket Design
The WebSocket layer is intentionally simple. Clients connect once and receive a continuous stream of events relevant to the configured channel.
- Broadcast-based model.
- Channel selection via shared configuration.
- Designed for frequent reconnects (OBS reloads).
- No per-client state stored on the server.
6. Kick Integration
The platform integrates with Kick on multiple levels: REST APIs, signed webhooks, OAuth token handling, and live chat consumption via WebSockets.
- OAuth-based token retrieval and refresh.
- Automatic event subscription on startup.
- RSA signature verification for incoming webhooks.
- Live chat consumption via Kick’s Pusher-based WS.
7. Security & Production Setup
In production, the server runs behind Nginx with HTTPS termination. Access to webhook endpoints and overlays is restricted using CORS and environment-based configuration.
- HTTPS terminated at Nginx.
- CORS allowlist for known overlay origins.
- Secrets stored per-project in environment variables.
- Mock endpoints available only in development mode.
8. Trade-offs & Constraints
The system deliberately avoids persistence and horizontal scaling. Every design decision favors low latency and operational simplicity.
- No database or event storage.
- No replay or recovery of missed events.
- Single-server deployment.
- Optimized for live usage, not analytics.
9. Future Work
The current architecture leaves room for multi-channel support, authentication, and additional event sources without rewriting the core pipeline.
Extensibility
Because the system is stateless and contract-driven, new providers or overlay types can be added with minimal impact on existing code.