Skip to main content

System Architecture

Watch N Chill is built on a custom Next.js server architecture with Socket.IO for real-time communication, Redis for state persistence, and React for the frontend.
The application uses a custom Next.js server instead of the standard Next.js server to integrate Socket.IO for bidirectional real-time communication.

Architecture Diagram

┌─────────────────────────────────────────────────────────────┐
│                         Client Layer                         │
│  ┌────────────────────────────────────────────────────────┐ │
│  │  Next.js App Router (React Components)                 │ │
│  │  - Room Pages (/room/[roomId])                         │ │
│  │  - Landing, Create, Join Pages                         │ │
│  └────────────────────────────────────────────────────────┘ │
│  ┌────────────────────────────────────────────────────────┐ │
│  │  React Context & Hooks                                  │ │
│  │  - SocketProvider (WebSocket management)               │ │
│  │  - useRoom, useVideoSync, useCreateRoom, useJoinRoom   │ │
│  └────────────────────────────────────────────────────────┘ │
│  ┌────────────────────────────────────────────────────────┐ │
│  │  Socket.IO Client                                       │ │
│  │  Path: /api/socket/io                                  │ │
│  └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│                         Server Layer                         │
│  ┌────────────────────────────────────────────────────────┐ │
│  │  Custom HTTP Server (server.ts)                        │ │
│  │  - Next.js request handler                             │ │
│  │  - Rate limiting middleware                            │ │
│  │  - Health check endpoint (/health)                     │ │
│  └────────────────────────────────────────────────────────┘ │
│  ┌────────────────────────────────────────────────────────┐ │
│  │  Socket.IO Server                                       │ │
│  │  - Connection management & authentication              │ │
│  │  - Event handlers (room, video, chat)                 │ │
│  │  - Zod schema validation                               │ │
│  └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│                      Persistence Layer                       │
│  ┌────────────────────────────────────────────────────────┐ │
│  │  Redis                                                  │ │
│  │  - Room state (24h TTL)                                │ │
│  │  - Chat messages (last 20 messages)                    │ │
│  │  - Active room tracking                                │ │
│  │  - Rate limit counters                                 │ │
│  └────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

Core Components

The application uses a custom Node.js HTTP server that integrates both Next.js and Socket.IO:
server.ts
const app = next({ dev, hostname, port });
const handle = app.getRequestHandler();

const httpServer = createServer(async (req, res) => {
  // Rate limiting
  const { allowed, remaining } = await checkRateLimit(req);
  if (!allowed) {
    res.statusCode = 429;
    res.end('Too Many Requests');
    return;
  }
  
  // Next.js request handling
  await handle(req, res, parsedUrl);
});

// Initialize Socket.IO
initSocketIO(httpServer);
This approach allows Socket.IO to share the same HTTP server as Next.js, enabling real-time features.
Socket.IO provides bidirectional event-based communication between clients and server:Key Features:
  • WebSocket with fallback to polling
  • Room-based event broadcasting
  • Connection state management
  • Automatic reconnection
Event Categories:
  • Room management (create, join, leave)
  • Video control (play, pause, seek, sync)
  • Chat messaging (send, typing indicators)
  • User management (promote to host)
Redis serves as the single source of truth for room state:Data Structures:
  • room:{roomId} - Complete room state (users, video, metadata)
  • chat:{roomId} - List of last 20 chat messages
  • active-rooms - Set of all active room IDs
  • rl:{ip} - Rate limit counters per IP
TTL Strategy:
  • Rooms: 24 hours (auto-cleanup)
  • Chat: 24 hours
  • Rate limits: 1 minute to 1 hour
The frontend uses Next.js App Router with a component-driven architecture:Page Structure:
  • / - Landing page
  • /create - Create room form
  • /join - Join room form
  • /room/[roomId] - Main room interface
State Management:
  • React Context for Socket.IO connection
  • Custom hooks for room and video sync logic
  • Local component state for UI
  • Session storage for user data

Data Flow

Room Creation Flow

User                Client              Server              Redis
 │                    │                    │                   │
 │──── Fill Form ────▶│                    │                   │
 │                    │──── create-room ───▶│                   │
 │                    │    {hostName}      │                   │
 │                    │                    │─── Generate ID ──▶│
 │                    │                    │   & Host Token    │
 │                    │                    │                   │
 │                    │                    │──── Save Room ───▶│
 │                    │                    │   (24h TTL)       │
 │                    │                    │                   │
 │                    │◀─── room-created ──│                   │
 │                    │    {roomId, token} │                   │
 │                    │                    │                   │
 │◀─ Navigate to ────│                    │                   │
 │   /room/[roomId]   │                    │                   │

Video Sync Flow

Host                 Guests              Server              Redis
 │                     │                    │                   │
 │──── Play Video ────▶│                    │                   │
 │                     │                    │                   │
 │    (every 5s)       │                    │                   │
 │──── sync-check ────▶│                    │                   │
 │  {time, playing}    │                    │                   │
 │                     │                    │                   │
 │                     │◀─── sync-update ───│                   │
 │                     │  {time, playing,   │                   │
 │                     │   timestamp}       │                   │
 │                     │                    │                   │
 │                     │─── Adjust Time ───▶│                   │
 │                     │   (if drift > 1.5s)│                   │

Technology Stack

Backend

  • Runtime: Node.js
  • Framework: Next.js 14+ (Custom Server)
  • WebSocket: Socket.IO v4
  • Validation: Zod schemas
  • Database: Redis (Upstash)

Frontend

  • Framework: React 18+ / Next.js 14+
  • Routing: App Router
  • Styling: Tailwind CSS
  • State: React Context + Hooks
  • WebSocket: Socket.IO Client

Key Design Decisions

Why Custom Server?Next.js serverless functions don’t support WebSocket connections. A custom server allows:
  • Long-lived Socket.IO connections
  • Shared state between HTTP and WebSocket
  • Fine-grained control over server lifecycle
  • Custom middleware (rate limiting)
Trade-offs:
  • Cannot deploy to Vercel
  • Need to manage server process
  • Deployed on platforms like Render, Railway, or AWS

Scalability Considerations

Current Limitations:
  • Single server instance (no horizontal scaling)
  • Socket.IO requires sticky sessions for multi-instance
  • Redis is single point of failure
Future Improvements:
  • Redis Cluster for high availability
  • Socket.IO adapter for multi-instance (Redis adapter)
  • Load balancer with sticky sessions
  • Separate WebSocket and HTTP servers

Next Steps

Backend Deep Dive

Explore server implementation, Socket.IO handlers, and Redis repositories

Frontend Architecture

Learn about React hooks, component structure, and state management

Real-Time Sync

Deep dive into video synchronization mechanism and drift correction

Development Guide

Set up your development environment and start contributing

Build docs developers (and LLMs) love