A full-stack Netflix clone built with the MERN stack (MongoDB, Express, React, Node.js) featuring video streaming, user authentication, personalized recommendations, and a responsive Netflix-style UI.
# Install Vercel CLI
npm install -g vercel
# Run the deployment script
./deploy.shπ For detailed deployment instructions, please see README-DEPLOYMENT.md
- JWT-based authentication
- User registration and login
- Protected routes
- User profiles with customization
- Subscription tiers
- Custom HTML5 video player
- Multiple quality options (360p, 480p, 720p, 1080p, 4K)
- Subtitle support (multiple languages)
- Resume playback from where you left off
- Progress tracking and watch history
- Fullscreen mode
- Volume controls
- Skip forward/backward (5 seconds)
- Collaborative filtering recommendation engine
- Genre-based recommendations
- "Continue Watching" with progress indicators
- "My List" feature to save videos
- Watch history tracking
- Personalized homepage
- Hero banner with featured content
- Horizontal scrolling carousels
- Hover previews on video cards
- Genre rows (Action, Comedy, Drama, etc.)
- Trending section
- Fully responsive (mobile, tablet, desktop)
- Smooth animations and transitions
- Video search functionality
- Genre filtering
- Similar content recommendations
- View count tracking
- Mobile-friendly design
- Node.js & Express.js - Server framework
- MongoDB & Mongoose - Database
- JWT - Authentication
- bcryptjs - Password hashing
- Cloudinary - Video hosting (ready to integrate)
- CORS - Cross-origin requests
- React 18 - UI library
- React Router - Navigation
- Axios - HTTP client
- Vite - Build tool
- CSS3 - Styling (Netflix theme)
- Node.js (v16+)
- MongoDB (local or Atlas)
- npm or yarn
- Cloudinary account (for video hosting)
```bash cd /Users/leooladimu1984/x/netflix-clone ```
```bash cd backend
npm install
cp .env.example .env ```
Edit .env with your configuration:
```env PORT=5000 MONGODB_URI=mongodb://localhost:27017/netflix-clone JWT_SECRET=your_super_secret_jwt_key_change_this JWT_EXPIRE=7d
CLOUDINARY_CLOUD_NAME=your_cloud_name CLOUDINARY_API_KEY=your_api_key CLOUDINARY_API_SECRET=your_api_secret
CLIENT_URL=http://localhost:5173 ```
Start MongoDB (if running locally): ```bash mongod ```
Start the backend server: ```bash npm run dev ```
Server runs on http://localhost:5000
Open a new terminal:
```bash cd frontend
npm install
npm run dev ```
Frontend runs on http://localhost:5173
Open http://localhost:5173 in your browser
``` netflix-clone/ βββ backend/ β βββ config/ β β βββ db.js # MongoDB connection β βββ controllers/ β β βββ authController.js # Auth logic β β βββ videoController.js # Video CRUD β β βββ recommendationController.js β βββ middleware/ β β βββ auth.js # JWT middleware β βββ models/ β β βββ User.js # User schema β β βββ Video.js # Video schema β βββ routes/ β β βββ authRoutes.js β β βββ videoRoutes.js β β βββ recommendationRoutes.js β βββ .env.example β βββ package.json β βββ server.js # Entry point β βββ frontend/ βββ src/ β βββ components/ β β βββ Navbar/ β β βββ VideoCard/ β β βββ VideoRow/ β β βββ VideoPlayer/ # Custom video player β βββ context/ β β βββ AuthContext.jsx # Auth state β βββ pages/ β β βββ Home/ # Main page β β βββ Login/ β β βββ Register/ β β βββ Watch/ # Video player page β β βββ MyList/ β β βββ Profile/ β βββ utils/ β β βββ api.js # Axios instance β βββ App.jsx β βββ main.jsx β βββ index.css βββ index.html βββ package.json βββ vite.config.js ```
POST /api/auth/register- Register new userPOST /api/auth/login- Login userGET /api/auth/me- Get current user (protected)PUT /api/auth/profile- Update profile (protected)
GET /api/videos- Get all videos (with filters)GET /api/videos/:id- Get single videoGET /api/videos/featured- Get featured videosGET /api/videos/trending- Get trending videosGET /api/videos/genre/:genre- Get videos by genrePOST /api/videos- Create video (protected)POST /api/videos/:id/watch- Add to watch history (protected)POST /api/videos/:id/mylist- Toggle My List (protected)
GET /api/recommendations- Get personalized recommendations (protected)GET /api/recommendations/similar/:id- Get similar videos
- Sign up at cloudinary.com
- Get your credentials from the Dashboard
- Add to
.envfile
Example video object structure:
```javascript { title: "Sample Movie", description: "A great movie", videoUrl: "https://res.cloudinary.com/your-cloud/video/upload/sample-video.mp4", thumbnail: "https://res.cloudinary.com/your-cloud/image/upload/thumbnail.jpg", duration: 7200, // seconds genre: ["Action", "Thriller"], quality: [ { resolution: "1080p", url: "video-1080p.mp4" }, { resolution: "720p", url: "video-720p.mp4" } ], subtitles: [ { language: "en", url: "subtitles-en.vtt" }, { language: "es", url: "subtitles-es.vtt" } ], releaseYear: 2024, rating: "PG-13" } ```
Create backend/seeder.js:
```javascript import mongoose from 'mongoose'; import dotenv from 'dotenv'; import Video from './models/Video.js'; import connectDB from './config/db.js';
dotenv.config(); connectDB();
const sampleVideos = [ { title: "Action Movie", description: "An epic action adventure", videoUrl: "your-cloudinary-url", thumbnail: "your-thumbnail-url", duration: 7200, genre: ["Action"], releaseYear: 2024, rating: "PG-13", featured: true } // Add more... ];
const seedData = async () => { await Video.deleteMany(); await Video.insertMany(sampleVideos); console.log('Data seeded!'); process.exit(); };
seedData(); ```
Run: node backend/seeder.js
Edit frontend/src/index.css:
```css :root { --netflix-red: #e50914; --netflix-black: #141414; --netflix-dark: #0b0b0b; --netflix-gray: #808080; } ```
Update backend/models/Video.js:
```javascript genre: [{ type: String, enum: ['Action', 'Comedy', 'Drama', 'Horror', 'Sci-Fi', 'Romance', 'Thriller', 'Documentary', 'Animation', 'Fantasy', 'YOUR_GENRE'] }] ```
The app is fully responsive with breakpoints:
- Mobile: < 768px
- Tablet: 768px - 1024px
- Desktop: > 1024px
- Password hashing with bcrypt
- JWT token authentication
- Protected API routes
- Input validation
- CORS configuration
- Environment variables for secrets
```bash
npm install
npm start ```
```bash
npm run build
dist ```
Set all .env variables in your hosting platform.
- Ensure MongoDB is running
- Check connection string in
.env - For MongoDB Atlas, whitelist your IP
- Verify
CLIENT_URLin backend.env - Check CORS configuration in
server.js
- Verify Cloudinary URLs
- Check video format (MP4 recommended)
- Ensure CORS is enabled on Cloudinary
- Fork the repository
- Create a feature branch
- Commit your changes
- Push to the branch
- Open a Pull Request
MIT License - feel free to use for personal or commercial projects
- Admin dashboard
- Content upload interface
- Advanced search filters
- User reviews and ratings
- Download for offline viewing
- Multiple user profiles
- Parental controls
- Watch parties (synchronized viewing)
For issues or questions, please open an issue on GitHub.
Happy Streaming! πΏ