A complete, production-ready Progressive Web Application for creating ephemeral watch parties with synchronized YouTube video playback and real-time chat.
- Room Management: Generate random 6-character room codes with automatic cleanup
- Video Synchronization: Host-controlled YouTube playback with real-time sync for all participants
- Real-time Chat: Socket.IO-powered messaging system with message history
- PWA Support: Full offline capabilities, installable app, mobile-responsive design
- AI Recommendations: Stub endpoint ready for Gemini API integration
- Ephemeral Design: No database required - all data stored in memory
- Node.js 18+
- npm or yarn
- Clone and install dependencies:
git clone <repository-url>
cd watch-party
npm run install:all- Start development servers:
npm run devThis starts both the backend server (port 3001) and Next.js frontend (port 3000) concurrently.
- Open your browser:
- Frontend: http://localhost:3000
- Backend API: http://localhost:3001
-
Connect to Netlify:
- Push your code to GitHub
- Connect your repository to Netlify
- Netlify will automatically detect the
netlify.tomlconfiguration
-
Environment Variables in Netlify:
- Set
NEXT_PUBLIC_SERVER_URLto your deployed backend URL - Example:
https://your-backend-app.herokuapp.com
- Set
-
Deploy:
- Netlify will build and deploy automatically on git push
- The
@netlify/plugin-nextjshandles SSR and routing
Since Netlify doesn't support persistent WebSocket connections, deploy the backend separately:
Recommended platforms:
- Railway (recommended for simplicity)
- Render (free tier available)
- Heroku (traditional choice)
- DigitalOcean App Platform
- Deploy backend to chosen platform
- Update frontend environment variable with the backend URL
- Redeploy frontend with new environment variable
Example Railway deployment:
# In server directory
railway login
railway init
railway upwatch-party/
โโโ package.json # Root package with scripts
โโโ server/
โ โโโ package.json # Backend dependencies
โ โโโ index.js # Socket.IO server & API
โโโ frontend/
โ โโโ package.json # Frontend dependencies
โ โโโ next.config.js # Next.js configuration
โ โโโ pages/
โ โ โโโ _app.js # App wrapper with PWA setup
โ โ โโโ index.js # Landing page
โ โ โโโ r/[code].js # Room page
โ โโโ styles/
โ โ โโโ globals.css # Global styles
โ โโโ public/
โ โโโ manifest.json # PWA manifest
โ โโโ sw.js # Service worker
โ โโโ favicon.ico # App icon
โโโ README.md
Development (frontend/.env.local):
NEXT_PUBLIC_SERVER_URL=http://localhost:3001 # Backend server URLProduction (Netlify Dashboard):
- Go to Site Settings โ Environment Variables
- Add:
NEXT_PUBLIC_SERVER_URL=https://your-backend-domain.com
PORT=3001 # Server port
NODE_ENV=development # Environment modeThe backend is configured for development CORS. For production:
- Update
server/index.jsCORS settings:
const io = new Server(server, {
cors: {
origin: "https://your-frontend-domain.com",
methods: ["GET", "POST"]
}
});- Update
frontend/next.config.js:
env: {
NEXT_PUBLIC_SERVER_URL: 'https://your-backend-domain.com'
}- Enter a username on the homepage
- Click "Create New Room"
- Share the generated room code or copy the room link
- Enter a username and the 6-character room code
- Click "Join Room"
- You'll be synchronized with the current video state
- Load Videos: Paste any YouTube URL to load videos for the room
- Playback Control: Play, pause, and seek controls sync to all participants
- AI Recommendations: Get suggested videos (currently returns placeholders)
- Real-time messaging with all room participants
- Message history preserved during the session
- Mobile-optimized interface
The application includes a stub endpoint for AI-powered video recommendations at /api/recommend.
- Install the Gemini SDK:
cd server && npm install @google/generative-ai- Add environment variable:
GEMINI_API_KEY=your_api_key_here- Update the recommendation endpoint in
server/index.js:
const { GoogleGenerativeAI } = require('@google/generative-ai');
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
app.get('/api/recommend', async (req, res) => {
const { videoId } = req.query;
try {
const model = genAI.getGenerativeModel({ model: "gemini-pro" });
const prompt = `Based on YouTube video ID ${videoId}, recommend 5 similar videos that would be good for a group watch party. Return only video IDs and titles in JSON format.`;
const result = await model.generateContent(prompt);
const response = await result.response;
const text = response.text();
// Parse and format the AI response
const recommendations = JSON.parse(text);
res.json({ recommendations });
} catch (error) {
console.error('AI recommendation error:', error);
// Fallback to placeholder recommendations
res.json({ recommendations: placeholderRecommendations });
}
});The endpoint can easily be adapted for other AI services:
- OpenAI GPT: Replace Gemini calls with OpenAI API
- Anthropic Claude: Use Claude API for recommendations
- Custom ML Models: Integrate your own recommendation engine
- Desktop: Install button appears in browser address bar
- Mobile: Add to Home Screen option in browser menu
- Automatic: PWA install prompt shows after user engagement
- App Shell: Core application files cached for offline access
- Smart Caching: Static assets cached, dynamic content handled gracefully
- Video Exclusion: YouTube videos are never cached to prevent storage bloat
- Responsive Design: Optimized layouts for mobile, tablet, and desktop
- Touch-Friendly: Proper touch targets and gestures
- Status Bar: Integrated with mobile status bar styling
- Videos are embedded using YouTube's IFrame API
- Cross-origin restrictions apply - some videos may not be embeddable
- Corporate/restricted videos may fail to load
- Configure CORS properly for production domains
- Update
next.config.jswith production server URLs - Consider implementing domain whitelisting
- All data is ephemeral and stored only in server memory
- No user data persistence or tracking
- Chat messages are cleared when rooms are cleaned up
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
- Internet Explorer: Not supported (lacks Socket.IO and PWA features)
- Older mobile browsers: Basic functionality only
- WebSockets/Socket.IO support
- Service Worker API
- YouTube IFrame API compatibility
- ES6+ JavaScript features
- Memory Storage: Server restarts clear all room data
- Scalability: Single-server architecture limits concurrent users
- Video Compatibility: Some YouTube videos have embedding restrictions
- Network Dependency: Real-time features require stable internet connection
- No Persistence: Chat history and room state lost on refresh
- Single Host: Only room creator has video control
- No User Authentication: Simple username-based identification
- Room Capacity: No built-in user limits per room
- Add Redis for distributed session storage
- Implement user authentication and persistent profiles
- Add room capacity limits and moderation tools
- Integrate video queue management
- Add mobile app versions with native features
- Backend API Routes: Add to
server/index.js - Socket Events: Define in both server and client code
- Frontend Pages: Add to
frontend/pages/ - Styling: Update
frontend/styles/globals.css
- Server Logs: Check console output from server process
- Client Logs: Use browser developer tools
- Socket Events: Monitor Socket.IO debug messages
- PWA Issues: Check Application tab in Chrome DevTools
# Test server endpoints
curl http://localhost:3001/api/room/TEST123
# Test room creation
curl -X POST http://localhost:3001/api/create-room
# Test recommendations
curl http://localhost:3001/api/recommend?videoId=dQw4w9WgXcQMIT License - feel free to use this project as a foundation for your own watch party applications.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Built with โค๏ธ for synchronized entertainment experiences