← Back to Projects

leptons1618@anishgiri.dev:~/projects/streamfusion cat project.toml

Full-Stack 2023 Stable

StreamFusion

Synchronised watch parties with no account and nothing to install — an Expo client sharing playback over WebRTC data channels, with one small WebSocket server holding the room together.

category
Full-Stack
year
2023
status
Stable
stack
7 tools
highlights
6
write-up
2 min read

01Highlights

  1. Playback sync travels peer-to-peer over WebRTC data channels, so a tick never has to round-trip through the server.
  2. A single `ws` signal server handles room membership and negotiation, sharing the Express port through `noServer: true`.
  3. Rooms are addressed three ways — id, short join code and peer — so every membership lookup is a map read rather than a scan.
  4. Zustand keeps playback position, the shared queue and room membership consistent across components.
  5. No account anywhere: you get a code, you join, and nothing is stored against you.
  6. Ships as an Expo client and a Next.js web surface out of one repository.

02Built with

  • 01React Native
  • 02Expo
  • 03TypeScript
  • 04WebRTC
  • 05Zustand
  • 06WebSocket
  • 07Node.js

03Case study

September 16, 2023 2 min read 528 words

StreamFusion — Two Transports, Because Sync and Signalling Are Different Problems

Peer-to-peer data channels for playback ticks, one WebSocket for everything the room has to agree on centrally.

The problem

Watch-party apps fail quickly when playback drift accumulates across devices, leading to broken group experiences and fragmented session state.

The solution

Built a room-based sync architecture using WebRTC data channels and WebSocket signaling, with reconciliation logic for playback state, queue coordination, and chat delivery.

Outcomes

  • WebRTC data channels carry latency-sensitive sync events peer-to-peer, so a tick never has to round-trip through the server.
  • A `ws` signal server shares a single Express port via `noServer: true`, rather than opening a second listener.
  • `RoomManager` indexes rooms three ways — by id, by short join code and by peer — so membership is a map read in every direction.

+3 more in the write-up

Inside the write-up

  1. What a watch party actually has to solve
  2. Two transports, on purpose
  3. Rooms are three maps
  4. Client state is Zustand, and that is the point
  5. The honest gaps
Read the full case study →

Related projects