// PROJECT_
WatchIt
01. LIVE_DEMO
// LIVE PREVIEW
WatchIt →
02. PROJECT_OVERVIEW
Some of the best moments in life happen in front of a screen — not because of what's on it, but because of who's next to you. WatchIt is for the people who don't have that luxury. The friend who moved to another country. The family scattered across time zones. The couple doing long distance. The ones who would give anything to just sit on the same couch for a night. WatchIt lets you create a room, share a link, and watch YouTube videos in perfect sync — no accounts, no setup, no friction. One person presses play, everyone watches together. Pause, seek, switch videos — it all stays in sync, instantly. Distance doesn't disappear, but for a while it stops mattering. Under the hood: a React 19 PWA with Socket.IO-driven play/pause/seek sync, and a stateless Node.js server with a custom handshake protocol that achieves frame-accurate join-time sync with zero server-side state. The technical challenge was making it feel effortless — because the point was never the technology. The point is that two people on opposite sides of the world can laugh at the same moment, at the same time. That's the whole thing.
Status
Active Development
Scope
Full-Stack Architecture
Primary Stack
React 19
Repo
Public
03. TECH_STACK & ARCHITECTURE
//React SPA (two routes: Home + Room) — Redux store holds search results and active video
//Socket.IO client joins a named room on connect, leaves on unmount — rooms are ephemeral
//Veteran sync handshake: new joiner asks oldest peer for current time + video on entry
//YouTube player events (play/pause/seek) emitted to server, relayed to all peers except sender
//YouTube search proxied through backend — API key stays in Railway env, never exposed to client
//PWA via vite-plugin-pwa — installable as a native-feeling app on desktop and mobile
React 19 + Vite
Frontend — UI Framework
SPA with two routes: Home (room creation) and Room (video + chat). Vite handles fast HMR in dev and tree-shaken production bundles.
Socket.IO Client 4.8
Frontend — Real-Time Sync
Connects on room entry, disconnects on leave. Emits play/pause/seek events from the YouTube player API and applies incoming events from peers — with echo prevention so the sender doesn't react to its own events.
react-youtube
Frontend — Video Player
Wraps the YouTube IFrame API. Exposes seekTo, playVideo, pauseVideo — the socket event handler calls these directly to apply remote state changes without reloading the component.
Redux Toolkit
Frontend — State Management
Stores video search results and the active videoId. Async Thunk proxies YouTube search through the backend so the Google API key never reaches the browser.
vite-plugin-pwa
Frontend — Progressive Web App
Service worker + web manifest make WatchIt installable on desktop and mobile. Users can launch it like a native app directly from their home screen.
Node.js + Express 5
Backend — Runtime & HTTP Server
Minimal Express app — no database, no sessions. Serves the YouTube search proxy route and hosts the Socket.IO server on the same port.
Socket.IO 4.8 Server
Backend — WebSocket Event Bus
Manages rooms as ephemeral sets of socket IDs. Relays video-event (play/pause/seek), change-video and chat-message to the correct room. All sync state lives in the browsers — the server is a pure relay.
Veteran Sync Handshake
Backend — Join-Time Synchronization
When a new peer joins, the server finds the oldest socket in the room (the 'veteran') and requests the current time + video ID from it. The veteran responds and the server forwards it only to the new joiner — frame-accurate sync with zero server-side state.
YouTube Data API v3 Proxy
Backend — Search Proxy
GET /youtube-search proxies video search via Axios. Keeps the Google API key in a Railway environment variable — the client never sees it. Results mapped to { videoId, title, thumbnail }.