Skip to content

Repository files navigation

🎬 Streamify

A Modern Full-Stack Video Streaming Platform

React Node.js MongoDB Express Tailwind CSS License

Streamify is a production-ready video streaming platform similar to YouTube, featuring video uploads, user authentication, playlists, subscriptions, and more. Built with modern technologies and best practices.

Features Β· Demo Β· Installation Β· Documentation Β· Contributing


πŸ“‘ Table of Contents


✨ Features

πŸŽ₯ Video Management

Feature Description
Video Upload Upload videos up to 2GB with drag-and-drop support
Auto Compression Server-side video compression using FFmpeg
Custom Player Built-in video player with playback controls
Thumbnails Auto-generated or custom thumbnail upload
Publish Control Publish/unpublish videos with one click
Video Editing Update title, description, tags, and thumbnail

πŸ‘€ User System

Feature Description
Email Verification Secure email verification on registration
Password Reset Email-based password recovery
Profile Management Custom avatars and cover images
Channel System Each user has their own channel
JWT Authentication Secure token-based authentication
Session Management Auto token refresh, graceful logout

πŸ“Ί Social Features

Feature Description
Subscriptions Subscribe to channels you love
Like/Dislike React to videos
Comments Comment on videos with replies
Watch History Track your viewing history
Watch Later Save videos to watch later
Playlists Create and manage playlists

πŸ›‘οΈ Security & Performance

Feature Description
Rate Limiting Protection against brute force attacks
Helmet HTTP security headers
CORS Configurable cross-origin settings
Input Validation Express-validator for all inputs
Lazy Loading React.lazy for code splitting
GZIP Compression Reduced response sizes

πŸ–ΌοΈ Demo

πŸ“Έ Screenshots

Home Page Video Player User Profile
Home Page Video Player User Profile

πŸŽ₯ Live Demo

Live Link: https://streamify-demo.vercel.app (Coming Soon)


❓ Troubleshooting

MongoDB Connection Error
  • Ensure your IP is whitelisted in MongoDB Atlas or allow all IPs (0.0.0.0/0).
  • Check if MONGODB_URL in .env is correct and includes username/password.
  • If password has special characters, URL encode them.
Cloudinary Upload Failed
  • Verify CLOUD_NAME, API_KEY, and API_SECRET in backend/.env.
  • Ensure your internet connection is stable.
  • Check file size limits in constants.js (default 2GB for video).
Email Not Sending
  • Ensure you are using an App Password for Gmail, not your login password.
  • Check if SMTP_HOST and SMTP_PORT are correct.
  • Verify EMAIL_FROM is a valid email address.
CORS Error
  • Ensure CORS_ORIGIN in backend/.env matches your frontend URL (e.g., http://localhost:5173).
  • If testing from a different device, ensure backend is accessible via network IP.

πŸ› οΈ Tech Stack

Frontend

Technology Version Purpose
React 18.3 UI library with hooks
Vite 6.0 Build tool & dev server
TailwindCSS 3.4 Utility-first CSS
Framer Motion 12.6 Animations
React Router 7.1 Client-side routing
Axios 1.9 HTTP client
React Hot Toast 2.5 Toast notifications
Heroicons 2.2 Icon library

Backend

Technology Version Purpose
Node.js 18+ JavaScript runtime
Express 4.21 Web framework
MongoDB 7.0 NoSQL database
Mongoose 8.9 MongoDB ODM
Cloudinary 2.5 Media storage & CDN
Nodemailer 6.9 Email service
FFmpeg - Video processing
JWT 9.0 Authentication

DevOps & Tools

Tool Purpose
ESLint Code linting
Prettier Code formatting
Nodemon Dev auto-reload
Handlebars Email templates

πŸ—οΈ Architecture

System Overview

System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                              πŸ–₯️ CLIENT LAYER                                β”‚
β”‚                     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                      β”‚
β”‚                     β”‚ Web Browser  β”‚  β”‚Mobile Browserβ”‚                      β”‚
β”‚                     β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚                β”‚
                              β–Ό                β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        βš›οΈ FRONTEND (React + Vite)                           β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ App.jsx β”‚β†’ β”‚React Router β”‚β†’ β”‚  Context   β”‚β†’ β”‚ Hooks β”‚β†’ β”‚ API Services β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                   β”‚ HTTP
                                                                   β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      πŸš€ BACKEND (Node.js + Express)                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ Express β”‚β†’ β”‚ Routes β”‚β†’ β”‚ Middleware β”‚β†’ β”‚ Controllers β”‚β†’ β”‚   Models    β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                   β”‚               β”‚
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β–Ό                    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           ☁️ EXTERNAL SERVICES                              β”‚
β”‚         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚
β”‚         β”‚   MongoDB    β”‚      β”‚  Cloudinary  β”‚      β”‚ Email Server β”‚        β”‚
β”‚         β”‚    Atlas     β”‚      β”‚     CDN      β”‚      β”‚    (SMTP)    β”‚        β”‚
β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Request Flow

  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  Client  β”‚          β”‚   API    β”‚          β”‚ Middleware β”‚          β”‚Controllerβ”‚
  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜          β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
       β”‚                     β”‚                      β”‚                      β”‚
       β”‚  HTTP Request       β”‚                      β”‚                      β”‚
       │────────────────────>β”‚                      β”‚                      β”‚
       β”‚                     β”‚                      β”‚                      β”‚
       β”‚                     β”‚  Rate Limit Check    β”‚                      β”‚
       β”‚                     │─────────────────────>β”‚                      β”‚
       β”‚                     β”‚                      β”‚                      β”‚
       β”‚                     β”‚                      β”‚  Auth Validation     β”‚
       β”‚                     β”‚                      │──────────────────────>
       β”‚                     β”‚                      β”‚                      β”‚
       β”‚                     β”‚                      β”‚                      β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚                     β”‚                      β”‚                      │─>β”‚ Database β”‚
       β”‚                     β”‚                      β”‚                      β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
       β”‚                     β”‚                      β”‚                      β”‚       β”‚
       β”‚                     β”‚                      β”‚                      β”‚<β”€β”€β”€β”€β”€β”€β”˜
       β”‚                     β”‚                      β”‚                      β”‚
       β”‚                     β”‚                      β”‚<─────────────────────│
       β”‚                     β”‚<─────────────────────│                      β”‚
       β”‚<────────────────────│                      β”‚                      β”‚
       β”‚   JSON Response     β”‚                      β”‚                      β”‚
       β”‚                     β”‚                      β”‚                      β”‚

Authentication Flow

                                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                    β”‚ Unauthenticated β”‚
                                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                             β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                        β”‚                        β”‚
                    β–Ό                        β–Ό                        β–Ό
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚   Register    β”‚        β”‚    Login     β”‚        β”‚Forgot Password β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚                       β”‚                        β”‚
                    β–Ό                       β”‚                        β–Ό
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚  Email Sent   β”‚               β”‚                β”‚  Reset Email   β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚                β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚                       β”‚                        β”‚
                    β–Ό                       β”‚                        β–Ό
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”‚                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚   Verified    β”‚               β”‚                β”‚ Password Reset β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜               β”‚                β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚                       β”‚                        β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                        β”‚
                                β”‚                                    β”‚
                                β–Ό                                    β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                        β”‚
                    β”‚    Authenticated      β”‚<β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚           β”‚           β”‚
                    β–Ό           β”‚           β–Ό
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚  Token Refresh   β”‚   β”‚   β”‚    Logout     β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚             β”‚           β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β”‚
                                            β–Ό
                                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                β”‚ Unauthenticated β”‚
                                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Installation

Prerequisites

Before you begin, ensure you have the following installed:

Requirement Version Check Command
Node.js 18+ node --version
npm 9+ npm --version
MongoDB 6+ mongod --version
FFmpeg 4+ ffmpeg -version
Git 2+ git --version

Step 1: Clone Repository

git clone https://github.com/Anurag-Basuri/streamify.git
cd streamify

Step 2: Install Dependencies

# Install backend dependencies
cd backend
npm install

# Install frontend dependencies
cd ../frontend
npm install

Step 3: Environment Setup

Create environment files in both directories (see Configuration section).

Step 4: Start Development Servers

Terminal 1 - Backend:

cd backend
npm run dev

Terminal 2 - Frontend:

cd frontend
npm run dev

Step 5: Access Application

Service URL
Frontend http://localhost:5173
Backend API http://localhost:8000
Health Check http://localhost:8000/health
API Status http://localhost:8000/status

βš™οΈ Configuration

Backend Environment Variables

Create backend/.env:

# ═══════════════════════════════════════════
# SERVER CONFIGURATION
# ═══════════════════════════════════════════
PORT=8000
NODE_ENV=development

# ═══════════════════════════════════════════
# DATABASE
# ═══════════════════════════════════════════
MONGODB_URL=mongodb+srv://username:password@cluster.mongodb.net
DB_NAME=streamify

# ═══════════════════════════════════════════
# AUTHENTICATION
# ═══════════════════════════════════════════
ACCESS_TOKEN_SECRET=your_super_secret_access_key_min_32_chars
REFRESH_TOKEN_SECRET=your_super_secret_refresh_key_min_32_chars
ACCESS_TOKEN_EXPIRY=15m
REFRESH_TOKEN_EXPIRY=7d
SESSION_SECRET=your_session_secret

# ═══════════════════════════════════════════
# CLOUDINARY (Media Storage)
# ═══════════════════════════════════════════
CLOUD_NAME=your_cloudinary_cloud_name
API_KEY=your_cloudinary_api_key
API_SECRET=your_cloudinary_api_secret

# ═══════════════════════════════════════════
# EMAIL CONFIGURATION (Optional)
# ═══════════════════════════════════════════
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_PASS=your_app_password
EMAIL_FROM="Streamify <noreply@streamify.com>"

# ═══════════════════════════════════════════
# CORS & FRONTEND
# ═══════════════════════════════════════════
CORS_ORIGIN=http://localhost:5173
FRONTEND_URL=http://localhost:5173

Frontend Environment Variables

Create frontend/.env:

VITE_API_URL=http://localhost:8000

Getting Required Credentials

πŸ“§ Gmail App Password (for Email)
  1. Go to Google Account Security
  2. Enable 2-Step Verification
  3. Go to App passwords
  4. Generate a new app password for "Mail"
  5. Use this password as SMTP_PASS
☁️ Cloudinary Credentials
  1. Sign up at Cloudinary
  2. Go to Dashboard
  3. Copy Cloud Name, API Key, and API Secret
  4. Use these in your .env file
πŸƒ MongoDB Atlas
  1. Sign up at MongoDB Atlas
  2. Create a new cluster
  3. Create a database user
  4. Get connection string from "Connect" button
  5. Replace <password> with your database user password

πŸ“š API Reference

Base URL

http://localhost:8000/api/v1

Authentication Endpoints

POST /users/register - Register new user

Request Body (multipart/form-data):

{
  "userName": "johndoe",
  "fullName": "John Doe",
  "email": "john@example.com",
  "password": "securepassword123",
  "avatar": "[file]"
}

Success Response (201):

{
  "statusCode": 201,
  "data": {
    "_id": "...",
    "userName": "johndoe",
    "email": "john@example.com",
    "isEmailVerified": false
  },
  "message": "Registration successful! Please check your email.",
  "success": true
}
POST /users/login - User login

Request Body:

{
  "email": "john@example.com",
  "password": "securepassword123"
}

Success Response (200):

{
  "statusCode": 200,
  "data": {
    "user": { ... },
    "accessToken": "eyJhbG...",
    "refreshToken": "eyJhbG..."
  },
  "message": "User logged in successfully",
  "success": true
}
GET /users/verify-email/:token - Verify email

Success Response (200):

{
  "statusCode": 200,
  "data": { "isEmailVerified": true },
  "message": "Email verified successfully",
  "success": true
}
POST /users/forgot-password - Request password reset

Request Body:

{
  "email": "john@example.com"
}

Response (200):

{
  "statusCode": 200,
  "data": null,
  "message": "If an account exists, a password reset email has been sent",
  "success": true
}

Video Endpoints

GET /videos - Get all videos

Query Parameters:

Parameter Type Default Description
page number 1 Page number
limit number 10 Items per page
sort string -createdAt Sort field

Success Response (200):

{
  "statusCode": 200,
  "data": {
    "videos": [...],
    "totalDocs": 100,
    "page": 1,
    "limit": 10,
    "hasNextPage": true,
    "hasPrevPage": false
  },
  "success": true
}
POST /videos/upload - Upload video

Headers:

Authorization: Bearer <accessToken>
Content-Type: multipart/form-data

Request Body:

Field Type Required Description
videoFile file Yes Video file (mp4, webm)
thumbnail file Yes Thumbnail image
title string Yes Video title
description string Yes Video description
tags string Yes JSON array of tags

Complete API Endpoint List

Category Method Endpoint Auth Description
Auth POST /users/register ❌ Register user
POST /users/login ❌ Login
POST /users/logout βœ… Logout
POST /users/refresh-token ❌ Refresh tokens
GET /users/verify-email/:token ❌ Verify email
POST /users/forgot-password ❌ Request reset
POST /users/reset-password/:token ❌ Reset password
User GET /users/current-user βœ… Get profile
PATCH /users/change-password βœ… Change password
PATCH /users/change-avatar βœ… Update avatar
PATCH /users/update-details βœ… Update profile
GET /users/c/:username ❌ Get channel
Videos GET /videos ❌ List videos
GET /videos/:id ❌ Get video
POST /videos/upload βœ… Upload video
PATCH /videos/update/:id βœ… Update video
DELETE /videos/:id βœ… Delete video
PATCH /videos/:id/publish βœ… Toggle publish
POST /videos/:id/views ❌ Increment views
Playlists GET /playlists βœ… Get playlists
POST /playlists βœ… Create playlist
PATCH /playlists/:id βœ… Update playlist
DELETE /playlists/:id βœ… Delete playlist
Comments GET /comments/:videoId ❌ Get comments
POST /comments/:videoId βœ… Add comment
DELETE /comments/:id βœ… Delete comment
Likes POST /likes/video/:id βœ… Like video
POST /likes/comment/:id βœ… Like comment
Subscriptions POST /subscriptions/:channelId βœ… Toggle subscribe
GET /subscriptions βœ… Get subscriptions
History GET /history βœ… Get history
DELETE /history βœ… Clear history
Watch Later GET /watchlater βœ… Get watch later
POST /watchlater/:videoId βœ… Add to watch later

πŸ’Ύ Database Schema

Entity Relationships

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            DATABASE RELATIONSHIPS                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚   USER   │────────<β”‚  VIDEO   β”‚>────────│ PLAYLIST β”‚
    β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                    β”‚
         β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚    β”‚               β”‚               β”‚
         β–Ό    β–Ό               β–Ό               β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  LIKE    β”‚         β”‚ COMMENT  β”‚    β”‚ HISTORY  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚
         β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ SUBSCRIPTION β”‚         β”‚ WATCH LATER  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

    Legend:
    ──────< One-to-Many     >────── Many-to-One
    ──────○ Optional        ●────── Required

Collections Schema

πŸ‘€ User Collection
Field Type Description
_id ObjectId Primary key
userName String Unique username
email String Unique email
fullName String Display name
password String Hashed password
avatar String Profile image URL
coverImage String Banner image URL
isEmailVerified Boolean Email verification status
emailVerificationToken String Token for email verification
emailVerificationExpires Date Token expiry
passwordResetToken String Password reset token
passwordResetExpires Date Reset token expiry
refreshToken String JWT refresh token
createdAt Date Account creation date
updatedAt Date Last update date
πŸŽ₯ Video Collection
Field Type Description
_id ObjectId Primary key
title String Video title
description String Video description
videoUrl String Cloudinary video URL
thumbnailUrl String Thumbnail URL
videoPublicId String Cloudinary public ID
thumbnailPublicId String Thumbnail public ID
duration Number Video length in seconds
views Number View count
isPublished Boolean Publish status
isDeleted Boolean Soft delete flag
owner ObjectId Reference to User
tags String[] Video tags
πŸ“ Playlist Collection
Field Type Description
_id ObjectId Primary key
name String Playlist name
description String Playlist description
owner ObjectId Reference to User
videos ObjectId[] Array of Video references
πŸ’¬ Comment Collection
Field Type Description
_id ObjectId Primary key
content String Comment text
video ObjectId Reference to Video
owner ObjectId Reference to User
❀️ Like Collection
Field Type Description
_id ObjectId Primary key
video ObjectId Reference to Video (optional)
comment ObjectId Reference to Comment (optional)
likedBy ObjectId Reference to User
πŸ”” Subscription Collection
Field Type Description
_id ObjectId Primary key
subscriber ObjectId User who subscribed
channel ObjectId Channel being subscribed to

πŸ“‚ Project Structure

streamify/
β”‚
β”œβ”€β”€ πŸ“‚ frontend/                          # React Frontend Application
β”‚   β”œβ”€β”€ πŸ“‚ public/                        # Static assets
β”‚   β”œβ”€β”€ πŸ“‚ src/
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ components/                # Reusable UI components
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ Video/                 # Video player, cards, list
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ Playlist/              # Playlist components
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ Upload/                # File upload components
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ Profile/               # Profile components
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ Form/                  # Form components
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ Header.jsx             # Navigation header
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ Sidebar.jsx            # Side navigation
β”‚   β”‚   β”‚   └── πŸ“„ Modal.jsx              # Modal component
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ pages/                     # Route page components
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ Display/               # Home, Tweet, Subscription
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“‚ Account/               # History, Playlist, Videos
β”‚   β”‚   β”‚   └── πŸ“‚ You/                   # Profile, Auth, Create
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ context/                   # React Context providers
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ AuthContext.jsx        # Authentication state
β”‚   β”‚   β”‚   └── πŸ“„ ThemeContext.jsx       # Theme management
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ services/                  # API client & services
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ api.js                 # Axios instance & config
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ authService.js         # Auth API calls
β”‚   β”‚   β”‚   └── πŸ“„ videoService.js        # Video API calls
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ hooks/                     # Custom React hooks
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ useAuth.js             # Auth hook
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ useDebounce.js         # Debounce hook
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ useLocalStorage.js     # LocalStorage hook
β”‚   β”‚   β”‚   └── πŸ“„ useVideos.js           # Videos hook
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ routes/                    # Route definitions
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ AppRoutes.jsx          # All routes (lazy loaded)
β”‚   β”‚   β”‚   └── πŸ“„ ProtectedRoute.jsx     # Auth guard
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ constants/                 # App constants
β”‚   β”‚   β”‚   └── πŸ“„ index.js               # Centralized constants
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“„ App.jsx                    # Root component
β”‚   β”‚   β”œβ”€β”€ πŸ“„ main.jsx                   # Entry point
β”‚   β”‚   └── πŸ“„ index.css                  # Global styles
β”‚   β”‚
β”‚   β”œβ”€β”€ πŸ“„ package.json
β”‚   β”œβ”€β”€ πŸ“„ vite.config.js
β”‚   └── πŸ“„ tailwind.config.js
β”‚
β”œβ”€β”€ πŸ“‚ backend/                           # Node.js Backend Application
β”‚   β”œβ”€β”€ πŸ“‚ src/
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ controllers/               # Request handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ user.controller.js     # User operations
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ video.controller.js    # Video CRUD
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ email.controller.js    # Email verification
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ playlist.controller.js # Playlist operations
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ comment.controller.js  # Comment operations
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ like.controller.js     # Like operations
β”‚   β”‚   β”‚   └── πŸ“„ subscription.controller.js
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ routes/                    # Express routes
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ user.routes.js         # /api/v1/users
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ video.routes.js        # /api/v1/videos
β”‚   β”‚   β”‚   └── πŸ“„ ...                    # Other routes
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ models/                    # Mongoose schemas
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ user.model.js
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ video.model.js
β”‚   β”‚   β”‚   └── πŸ“„ ...
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ middlewares/               # Express middleware
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ auth.middleware.js     # JWT verification
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ multer.middleware.js   # File upload
β”‚   β”‚   β”‚   └── πŸ“„ validate.middleware.js # Input validation
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ utils/                     # Utility functions
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ cloudinary.js          # Cloudinary helpers
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ email.js               # Email service
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ APIerror.js            # Error class
β”‚   β”‚   β”‚   └── πŸ“„ APIresponse.js         # Response class
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ templates/                 # Email templates
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ verify-email.hbs
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ welcome.hbs
β”‚   β”‚   β”‚   β”œβ”€β”€ πŸ“„ password-reset.hbs
β”‚   β”‚   β”‚   └── πŸ“„ password-changed.hbs
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ database/                  # Database connection
β”‚   β”‚   β”‚   └── πŸ“„ index.js               # MongoDB connection
β”‚   β”‚   β”‚
β”‚   β”‚   β”œβ”€β”€ πŸ“„ app.js                     # Express app setup
β”‚   β”‚   β”œβ”€β”€ πŸ“„ index.js                   # Server entry point
β”‚   β”‚   └── πŸ“„ constants.js               # Backend constants
β”‚   β”‚
β”‚   β”œβ”€β”€ πŸ“„ package.json
β”‚   └── πŸ“„ .env.example
β”‚
β”œβ”€β”€ πŸ“„ README.md
└── πŸ“„ LICENSE

πŸ”§ Development

Available Scripts

Backend:

npm run dev      # Start with nodemon (hot reload)
npm run start    # Production start

Frontend:

npm run dev      # Start Vite dev server
npm run build    # Production build
npm run preview  # Preview production build
npm run lint     # Run ESLint

Code Style

  • ESLint for JavaScript linting
  • Prettier for code formatting
  • Conventional Commits for commit messages

Testing API Endpoints

Use the following tools to test API:


🚒 Deployment

Frontend (Vercel/Netlify)

  1. Connect your GitHub repository
  2. Set build command: npm run build
  3. Set output directory: dist
  4. Add environment variables

Backend (Railway/Render)

  1. Connect your GitHub repository
  2. Set root directory: backend
  3. Set start command: npm start
  4. Add all environment variables

Docker (Coming Soon)

docker-compose up -d

πŸ—ΊοΈ Roadmap

🎯 Short-Term Goals (1-3 Months)

Category Feature Priority Status
🎨 UI/UX Dark/Light theme toggle πŸ”΄ High 🟑 In Progress
Mobile-responsive video player πŸ”΄ High πŸ“‹ Planned
Skeleton loading states 🟠 Medium πŸ“‹ Planned
Improved error messages & feedback 🟠 Medium πŸ“‹ Planned
πŸ”§ Backend Redis caching for videos πŸ”΄ High πŸ“‹ Planned
Video quality selection (360p, 720p, 1080p) πŸ”΄ High πŸ“‹ Planned
Improved video compression pipeline 🟠 Medium πŸ“‹ Planned
API documentation with Swagger 🟠 Medium πŸ“‹ Planned
πŸ” Security Two-factor authentication (2FA) 🟠 Medium πŸ“‹ Planned
OAuth providers (GitHub, Discord) 🟒 Low πŸ“‹ Planned
Account activity logging 🟒 Low πŸ“‹ Planned
✨ Features Video chapters/timestamps 🟠 Medium πŸ“‹ Planned
Nested comment replies 🟠 Medium πŸ“‹ Planned
Share video to social media 🟒 Low πŸ“‹ Planned

πŸš€ Long-Term Goals (3-12 Months)

Category Feature Description
πŸ“Ί Streaming Live Streaming Real-time video broadcasting with WebRTC/HLS
Adaptive Bitrate Streaming Auto-adjust quality based on network conditions
Live Chat Real-time chat during live streams with WebSocket
πŸ’° Monetization Creator Payments Stripe integration for channel memberships
Super Chat / Tips Allow viewers to tip creators during streams
Premium Subscriptions Ad-free experience for paying users
πŸ€– AI Features Auto-generated Captions Speech-to-text for video subtitles
Content Moderation AI-powered comment and video moderation
Video Recommendations ML-based personalized video suggestions
πŸ“± Platform Mobile Apps React Native apps for iOS and Android
Desktop App Electron app for Windows/Mac/Linux
TV Apps Smart TV applications (Android TV, Roku)
πŸ”§ Infrastructure Microservices Architecture Split into video, user, notification services
Kubernetes Deployment Container orchestration for scalability
Global CDN Multi-region video delivery network
πŸ“Š Analytics Creator Dashboard Detailed analytics for video performance
Viewer Insights Watch time, retention, demographics
Revenue Reports Earnings breakdown and payout history

πŸ“Œ Feature Request

Have an idea? Open an issue with the enhancement label!


🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'feat: add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Commit Convention

Prefix Description
feat: New feature
fix: Bug fix
docs: Documentation
style: Formatting
refactor: Code restructuring
test: Tests
chore: Maintenance

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ‘€ Author

Anurag Basuri

GitHub


⭐ Star this repo if you find it helpful!

Made with ❀️ and lots of β˜•

About

Streamify is a full-stack video streaming platform built with React, Node.js, and MongoDB. It provides a modern, responsive interface for uploading, sharing, and discovering videos, with features like playlists, watch later, history, and more.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages