I built Moka-fi as a cozy online café where friends can study, talk, play and spend time together. One of the newest rooms is Watch Together, where a group can watch a YouTube video while chatting or staying on a video call.

The interface looked simple on paper: a player, an Up Next queue and a chat. The synchronization behind it was not simple at all.

The player cannot be the source of truth

My first important decision was to separate the YouTube player from the shared state. The iframe is only a local view. The room owns the real state:

type WatchState = {