Mystery Internet Theater 3000
A synchronized YouTube video watching platform for group viewing with real-time chat, presence tracking, and MST3K-style fruit throwing.
Status
| Status | Active |
| Type | Personal Project |
| Domain | mit3k.com |
Links
Overview
Watch YouTube videos together in sync with friends:
- Synchronized Playback: All participants watch at the same timestamp
- Real-time Chat: Live messages via Supabase Realtime
- Room Management: Public or private rooms with unique codes
- Participant Presence: See who's watching with silhouettes
- Fruit Throwing: Interactive MST3K-style fruit throwing at the screen
- Video Timestamps: Chat messages linked to video timestamps
Tech Stack
- Framework: Next.js 16 (App Router)
- UI: React 19, Tailwind CSS 4
- Database: Supabase (PostgreSQL)
- Auth: NextAuth.js v5 (GitHub, Google OAuth)
- Real-time: Supabase Realtime (WebSocket)
- Language: TypeScript
Setup & Development
npm install
# Configure environment
cp .env.example .env.local
# Add: Supabase credentials, NextAuth secret, OAuth keys, YouTube API key
# Run database migrations (in Supabase SQL Editor)
# 001_initial_schema.sql through 006_add_participant_presence.sql
npm run dev
Architecture
Database Schema
| Table | Purpose |
|---|---|
users | Profiles with emoji avatars |
rooms | Room metadata, current video, sync state |
room_participants | Who's in each room + presence |
chat_messages | Messages with optional video timestamps |
Real-time Features
- Chat: Supabase Realtime subscriptions on
chat_messages - Fruit Throwing: Broadcast via Supabase Realtime channels
- Presence: Heartbeat tracking every 30 seconds
Fruit Throwing
Press F to toggle fruit mode, then click anywhere on the video to throw:
- Fruit animates from participant's silhouette to target
- Different fruits have different physics (heavier = slower drip)
- Available: 🍎 🍌 🍊 🍓 🍇 🥝 🍑 🍒 🍉 🍐 🥭 🍍 🥥 🫐 🍈 🥑 🍆
API Endpoints
Rooms
GET /api/rooms- List roomsPOST /api/rooms- Create roomGET /api/rooms/[code]- Get room detailsPUT /api/rooms/[code]/video- Update current video
YouTube
GET /api/youtube/metadata- Get video metadataGET /api/youtube/search- Search videosGET /api/youtube/suggestions- Trending/live suggestions
Socket
POST /api/socket/fruit-throw- Throw fruitPOST /api/socket/heartbeat- Update presence
Environment Variables
# Supabase
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
SUPABASE_SERVICE_ROLE_KEY=
# Auth
AUTH_SECRET= # openssl rand -base64 32
# OAuth
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# YouTube
NEXT_PUBLIC_YOUTUBE_API_KEY=
Handoff Notes
Database Migrations
Run migrations in order (001-006) in Supabase SQL Editor. Each builds on the previous.
OAuth Callback URLs
Update callback URLs when deploying:
- GitHub:
https://mit3k.com/api/auth/callback/github - Google:
https://mit3k.com/api/auth/callback/google