2026 · completed · web
Ruse
Ruse is a private, temporary collaboration room for small groups to share screens, system audio, camera, microphone, and chat without creating accounts or storing conversations.
overview
Ruse is a real-time screen-sharing platform designed for small, private groups. A user can create a temporary room, share its code, review incoming join requests, and approve participants before they enter.
Once inside, participants can communicate using voice, camera, screen sharing, and ephemeral chat. The room owner controls admission and can end the session at any time. Rooms automatically expire after eight hours or are cleaned up when left empty.
The platform supports up to eight participants in each room and limits the system to three active rooms at a time. This capacity is enforced using Redis-backed reservations to prevent race conditions when multiple users try to create or join rooms simultaneously.
Ruse uses LiveKit Cloud for low-latency WebRTC media transport. The Go backend handles room creation, authentication, participant approvals, temporary sessions, presence, capacity management, and LiveKit token generation. Redis stores temporary room state, hashed room codes, session tokens, queue data, and participant presence.
The frontend is built with Next.js and provides the complete room experience, including participant tiles, fullscreen mode, video pinning, draggable and resizable floating video, owner controls, ephemeral chat, and device management.
at a glance
architecture
sequenceDiagram
actor Owner
actor Guest
participant UI as Next.js Frontend
participant API as Go API
participant Redis as Redis
participant LiveKit as LiveKit Cloud
Owner->>UI: Create a private room
UI->>API: POST /api/v1/rooms
API->>Redis: Check and reserve room capacity
API->>Redis: Store room and owner session
Redis-->>API: Room created
API-->>UI: Return room code and owner session
UI-->>Owner: Display share code
Guest->>UI: Enter room code
UI->>API: POST /api/v1/rooms/join-requests
API->>Redis: Validate hashed room code
API->>Redis: Store pending join request
API-->>UI: Join request submitted
UI-->>Guest: Wait for approval
API-->>UI: Send join request event
UI-->>Owner: Show pending guest
Owner->>UI: Approve guest
UI->>API: Approve join request
API->>Redis: Validate owner session
API->>Redis: Reserve participant capacity
API->>Redis: Create guest session
API-->>UI: Guest approved
API-->>UI: Send approval event
UI-->>Guest: Allow room entry
Guest->>UI: Join media session
UI->>API: POST /api/v1/rooms/{roomId}/media/token
API->>Redis: Validate room and guest session
API->>LiveKit: Generate scoped access token
LiveKit-->>API: Return short-lived token
API-->>UI: Return LiveKit token
Owner->>UI: Join media session
UI->>API: Request owner media token
API->>Redis: Validate owner session
API->>LiveKit: Generate owner access token
LiveKit-->>API: Return short-lived token
API-->>UI: Return LiveKit token
UI->>LiveKit: Connect participants through WebRTC
Owner->>LiveKit: Publish screen, system audio, camera, and microphone
Guest->>LiveKit: Publish camera and microphone
LiveKit-->>UI: Deliver media tracks and ephemeral chat
Owner->>UI: End room
UI->>API: POST /api/v1/rooms/{roomId}/end
API->>Redis: Remove room, sessions, and presence
API-->>UI: Room ended
UI-->>Owner: Close room
UI-->>Guest: Disconnect from roomchallenges
- 01
Managing Temporary Room State
Room codes, sessions, approvals, participants, and presence had to remain temporary while still being accessible across backend instances. How I tackled it: I used Redis as the central temporary state store and assigned expiration times to rooms, sessions, join requests, and presence records.
- 02
Preventing Room Capacity Race Conditions
Multiple users could attempt to create rooms or join the final participant slot at the same time. Basic read-and-write operations could exceed the configured limits. How I tackled it: I implemented Redis-backed capacity reservations and atomic state transitions so room and participant limits remain consistent under concurrent requests.
- 03
Implementing Owner-Controlled Admission
Guests needed to request access and wait for approval without being given room or media access too early. How I tackled it: I separated join requests from participant sessions. A valid session is created only after the owner approves the request.
- 04
Capturing Desktop Audio in a Web Application
Screen sharing with system audio depends on browser and operating-system capabilities and is not handled like normal microphone audio. How I tackled it: I used the browser screen-capture APIs with LiveKit publishing and exposed system-audio sharing only when supported by the selected capture source and browser.
- 05
Synchronizing API Presence with LiveKit Participants
