Skip to main content

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

StatusActive
TypePersonal Project
Domainmit3k.com

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

Open http://localhost:3000

Architecture

Database Schema

TablePurpose
usersProfiles with emoji avatars
roomsRoom metadata, current video, sync state
room_participantsWho's in each room + presence
chat_messagesMessages 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 rooms
  • POST /api/rooms - Create room
  • GET /api/rooms/[code] - Get room details
  • PUT /api/rooms/[code]/video - Update current video

YouTube

  • GET /api/youtube/metadata - Get video metadata
  • GET /api/youtube/search - Search videos
  • GET /api/youtube/suggestions - Trending/live suggestions

Socket

  • POST /api/socket/fruit-throw - Throw fruit
  • POST /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