A modern, real-time YouTube watch party application built with Next.js 14, React, and Socket.IO. Watch videos in perfect sync with friends, chat in real-time, and search for videos together.
- 🎬 Synchronized Playback - Watch YouTube videos in perfect sync with all room members
- 🔴 Real-time Controls - Play, pause, and seek synchronized across all viewers
- 💬 Live Chat - Chat with friends while watching
- 🔍 Video Search - Search and select YouTube videos directly in the app
- 👥 Multi-user Rooms - Create or join rooms with a simple room code
- 👑 Host Management - Automatic host transfer when the original host leaves
- 📱 Responsive Design - Works seamlessly on desktop and mobile devices
- 🎨 Modern UI - Beautiful interface built with Tailwind CSS and shadcn/ui
- Next.js 14 - React framework with App Router
- React 18 - UI library
- TypeScript - Type-safe development
- Socket.IO Client - Real-time communication
- Tailwind CSS - Utility-first CSS framework
- shadcn/ui - Beautiful UI components
- react-youtube - YouTube player integration
- Lucide React - Icon library
- Node.js (v18 or higher)
- npm or yarn
- Backend server running (See server README)
- Clone the repository:
git clone <repository-url>
cd frontend- Install dependencies:
npm install- Create a
.env.localfile in the frontend directory:
NEXT_PUBLIC_SERVER_URL=http://localhost:5000npm run devOpen http://localhost:3000 in your browser.
npm run build
npm startfrontend/
├── app/
│ ├── page.tsx # Home page (create/join room)
│ ├── layout.tsx # Root layout
│ ├── globals.css # Global styles
│ └── room/
│ ├── create/
│ │ └── page.tsx # Create room page
│ └── [roomId]/
│ └── page.tsx # Room page (main app)
├── components/
│ ├── ui/ # shadcn/ui components
│ ├── VideoPlayer.tsx # YouTube player with sync
│ ├── ChatPanel.tsx # Real-time chat
│ └── VideoSearch.tsx # Video search interface
├── lib/
│ ├── socket.ts # Socket.IO client configuration
│ └── utils.ts # Utility functions
├── types/
│ └── room.ts # TypeScript type definitions
├── hooks/
│ └── use-toast.ts # Toast notification hook
├── public/ # Static assets
├── next.config.js # Next.js configuration
├── tailwind.config.js # Tailwind CSS configuration
├── tsconfig.json # TypeScript configuration
└── package.json # Dependencies
Handles YouTube video playback and synchronization:
- Syncs play/pause/seek events across all users
- Requests sync state when joining
- Host broadcasts playback state to new joiners
Real-time chat functionality:
- Send and receive messages instantly
- Displays username and timestamp
- Auto-scrolls to latest messages
YouTube video search interface:
- Search videos using YouTube Data API
- Display thumbnails and video info
- Click to play video for all room members
- Enter your name (optional) on home page
- Click "Create New Room"
- Automatically redirected to your new room
- Share room code with friends
- Enter your name (optional) on home page
- Enter room code
- Click "Join Room"
- Instantly connected and synced
- Use search to find a video
- Click on video to start playing
- Use YouTube controls (play/pause/seek)
- All viewers stay synchronized
- Chat with friends while watching
| Variable | Required | Default | Description |
|---|---|---|---|
NEXT_PUBLIC_SERVER_URL |
Yes | http://localhost:5000 | Backend server URL |
The next.config.js includes:
- React StrictMode disabled - Prevents duplicate socket connections
- Image optimization - Disabled for YouTube thumbnails
- Webpack fallbacks - For Socket.IO client compatibility
// lib/socket.ts
const socket = getSocket(SERVER_URL);
socket.connect();// Play event
socket.on("play", ({ time }) => {
player.seekTo(time);
player.playVideo();
});
// Emit play event
socket.emit("play", { time: currentTime });Built with Tailwind CSS and shadcn/ui components:
<Button className="bg-blue-600 hover:bg-blue-700">Create Room</Button>interface ChatMessage {
type: "chat_message";
user: string;
text: string;
timestamp: number;
}
interface SearchResult {
id: { videoId: string };
snippet: {
title: string;
channelTitle: string;
thumbnails: { medium: { url: string } };
};
}- Host-based sync: Host controls are broadcast to all members
- Late join sync: New joiners request current state from host
- Automatic reconnection: Handles network interruptions gracefully
- 6-character room codes: Easy to share (e.g., "abc123")
- Automatic host transfer: First remaining member becomes host
- Member count display: See how many people are watching
- Copy room link: One-click sharing
- Loading states: Clear feedback during connections
- Toast notifications: Non-intrusive status updates
- Responsive layout: Adapts to screen size
- Keyboard shortcuts: Enter to send messages/search
// Check connection status
socket.on("connect_error", (error) => {
console.error("Connection error:", error);
});Solutions:
- Verify backend server is running
- Check
NEXT_PUBLIC_SERVER_URLin.env.local - Ensure CORS is configured on backend
- Check YouTube video ID is valid
- Verify YouTube Player API loaded
- Check browser console for errors
- Ensure only one browser tab per user
- Check network latency
- Verify host is connected
- Debounced sync events - Prevents excessive socket emissions
- Lazy component loading - Improves initial load time
- Memoized components - Reduces unnecessary re-renders
- Optimized images - Uses YouTube thumbnail URLs
- Chrome/Edge (recommended)
- Firefox
- Safari
- Mobile browsers (iOS Safari, Chrome Mobile)
- Semantic HTML structure
- Keyboard navigation support
- ARIA labels for interactive elements
- Screen reader friendly
Next.js hot reloading works automatically. Socket connections persist across hot reloads.
Add console logs to track socket events:
socket.onAny((event, ...args) => {
console.log(`Socket event: ${event}`, args);
});# Run linter
npm run lint
# Type check
npm run type-checkvercel deploySet environment variable:
NEXT_PUBLIC_SERVER_URL: Your production backend URL
- Build the application:
npm run build- Set environment variables
- Deploy the
.nextfolder - Ensure backend URL is correctly configured
- All socket events validated on backend
- No sensitive data in client-side code
- HTTPS recommended for production
- Rate limiting on backend API calls
- User authentication
- Private rooms with passwords
- Video playlists
- Reactions and emojis
- Screen sharing
- Voice chat integration
- Watch history
- Dark mode toggle
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
MIT
For issues and questions, please open an issue on GitHub.
Made with ❤️ for watching together