Skip to content
kmaniskPublic

About

Real-time watch parties with synchronized playback, voice chat, live reactions, GIFs and collaborative rooms.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Latest commit

 

History

53 Commits

Folders and files

Repository files navigation

Flickfolk logo

Flickfolk

Same movie. Same second.

Real-time watch parties with synchronized playback, voice chat, reactions and private local-file playback.

Live app · Architecture · Design · Deployment


React 19 TypeScript Node.js Socket.IO WebRTC Vite Playwright Render

Flickfolk watch room

Overview

Flickfolk lets people open a room, share an invite and watch the same media on the same timeline. The server keeps room and playback state authoritative while each browser handles media playback locally.

  • Room codes and invite links with no account required.
  • Synchronized play, pause, seek and source changes.
  • Host, Moderator and Participant roles with server-side permissions.
  • Participant control requests with Host/Moderator approval.
  • Late-join alignment, reconnect recovery and automatic host failover.
  • Peer-to-peer WebRTC voice chat with speaking indicators and movie ducking.
  • Reactions, text/GIF chat and responsive desktop/mobile layouts.
  • Local-file watch parties without uploading the video.
  • Direct media URLs, YouTube, HLS, MPEG-DASH and provider embeds.

Media

Source Support
YouTube Synchronized playback through the IFrame API
Direct video URLs Native browser playback, including signed and extensionless media URLs
HLS .m3u8 Native HLS where available, otherwise hls.js
MPEG-DASH .mpd dash.js over the same synchronized video engine
Local files MP4, WebM, MKV, MOV, AVI, MPEG, TS and other browser-decodable containers
Direct audio MP3, OGG, M4A and other browser-supported audio
Twitch VOD timeline sync plus capability-aware live playback
SoundCloud Track and playlist playback through the official widget
Spotify Official embed controls with provider-specific limits
Kick Official livestream embed

Container support still depends on codecs available in the viewer's browser and operating system. Flickfolk does not transcode media on the server.

Private local-file playback

Local files stay on each viewer's device. A Host or Moderator chooses a file, Flickfolk fingerprints a small sample in a Web Worker, and other viewers select their own copy.

Local File
    ↓
Browser Object URL
    ↓
HTML5 Video
    ↓
Flickfolk Sync Engine

Only a sanitized filename, size, duration and SHA-256 fingerprint are shared with the room. File bytes and filesystem paths never leave the device.

Exact copies match automatically. A different encode with nearly the same duration can be accepted explicitly with Use anyway. Refreshing intentionally requires selecting the local file again.

Room controls

Capability Host Moderator Participant
Play / pause Direct Direct Request
Seek Direct Direct Request
Change source Direct Direct Request
Approve requests Yes Yes No
Promote / demote Yes No No
Remove participant Yes No No
Chat / reactions / voice Yes Yes Yes

Permissions are validated by the server; disabled client controls are only UI feedback.

Architecture

Client intent
    ↓
Socket.IO
    ↓
Server validation + permissions
    ↓
Authoritative room/playback state
    ↓
Room broadcast
    ↓
Local playback + drift correction

The server owns room membership, roles, playback state and revisions. Browsers own media playback, UI state and peer-to-peer audio. The synchronization engine estimates clock offset, aligns late joiners, ignores stale revisions and corrects drift with small rate adjustments or seeks depending on the media provider.

apps/client      React/Vite UI, player adapters, voice and room experience
apps/server      Express, Socket.IO, validation, room state and signaling
packages/shared  shared types, permissions, media parsing and sync policy

See ARCHITECTURE.md for the deeper implementation notes.

Tech stack

Layer Technology
Frontend React 19, TypeScript, Vite
Backend Node.js, Express, Socket.IO
Realtime audio WebRTC
Playback HTML5 Media, YouTube IFrame API, hls.js, dash.js
Styling CSS, Figtree, JetBrains Mono
Testing Vitest, Playwright
Delivery Docker, GitHub Actions, Render

Screenshots

Home

Flickfolk Home desktop

Mobile

Flickfolk Home mobile Flickfolk Room mobile

Development

Requires Node.js 22.12+ and npm.

npm ci
cp .env.example .env
npm run dev

Production build:

npm run build
NODE_ENV=production npm start

Docker:

docker compose up --build

The production container runs as a non-root user and exposes /healthz.

Optional configuration

WebRTC voice works without an account. Public STUN is available by default; restrictive networks can use TURN.

STUN_URLS=
TURN_URLS=
TURN_USERNAME=
TURN_PASSWORD=

GIF search is optional and uses a server-side GIPHY key:

GIPHY_API_KEY=

Keyboard shortcuts

Key Action
Space / K Play or pause
J / L Seek -10s / +10s
F Toggle stage fullscreen
Escape Exit fullscreen / close transient UI
M Mute microphone after joining voice
/ Focus chat
C Copy invite
T Toggle sidebar

Playback shortcuts still follow the current user's room permissions.

Verification

npm run lint
npm run typecheck
npm test
npm run build
npm run test:e2e

Current suite:

  • 220 unit/integration tests
  • 41 Playwright browser tests
  • Docker build and non-root health smoke test in GitHub Actions

Deployment

Live: https://flickfolk.onrender.com

The React client and Socket.IO server run from the same Node service. Rooms are currently stored in memory, so active rooms are cleared when the service restarts.


Flickfolk
Same movie. Same second.

About

Real-time watch parties with synchronized playback, voice chat, live reactions, GIFs and collaborative rooms.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages