A modern, high-performance YouTube clone built as a lightweight MVP. VideoHub demonstrates clean full-stack architecture with optimized video streaming, atomic social mechanics, and real-time view counting without unnecessary cloud infrastructure bloat.
- Node.js - JavaScript runtime
- Express.js - Web framework for REST API
- TypeScript - Type-safe development
- Prisma ORM - Database toolkit with type-safe queries
- PostgreSQL - Relational database
- JWT - Authentication
- Multer - File upload handling
- Next.js - React framework with server-side rendering
- React - UI library
- TypeScript - Type-safe frontend development
- Axios - HTTP client for API requests
- TailwindCSS - Utility-first CSS framework
- React Player - Video player component
- Native HTML5 Video Streaming - HTTP 206 Partial Content protocol for timeline scrubbing and seeking
- Iframe Upload/Embed System - Support for both local file uploads and YouTube URL embedding
- Atomic Social Mechanics - Race-condition-free likes and subscriptions using database transactions
- Real-time Optimized View Counts - In-memory buffering with batch writes to prevent database overload
- User Authentication - JWT-based auth with optional Google OAuth integration
- Video Management - Upload, edit, delete, and search videos
- Comments System - Threaded comments on videos
- User Profiles - Custom avatars, banners, and channel descriptions
- Node.js (v18 or higher)
- PostgreSQL (v14 or higher)
- npm or yarn
git clone <repository-url>
cd VideoHubInstall backend dependencies:
cd backend
npm installInstall frontend dependencies:
cd ../frontend
npm installCreate a PostgreSQL database named videohub:
# Using psql
psql -U postgres
CREATE DATABASE videohub;
\qCopy the example environment file and configure it:
cd backend
cp .env.example .envEdit .env with your configuration:
# Database Configuration
DATABASE_URL="postgresql://postgres:your_password@localhost:5432/videohub"
# Server Configuration
PORT=5000
NODE_ENV=development
# JWT Configuration - Generate a strong secret using:
# node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
JWT_SECRET=your_generated_jwt_secret_here
# Google OAuth Configuration (optional)
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_CALLBACK_URL=http://localhost:5000/api/auth/google/callback
# Frontend Configuration
FRONTEND_URL=http://localhost:3000
ALLOWED_ORIGINS=http://localhost:3000Generate Prisma client and run migrations:
cd backend
npx prisma generate
npx prisma migrate devStart the backend server (in backend/ directory):
npm run devThe backend will run on http://localhost:5000
Start the frontend server (in a new terminal, in frontend/ directory):
npm run devThe frontend will run on http://localhost:3000
Open your browser and navigate to:
- Frontend:
http://localhost:3000 - Backend API:
http://localhost:5000
VideoHub/
├── backend/
│ ├── prisma/
│ │ ├── schema.prisma # Database schema
│ │ └── migrations/ # Database migrations
│ ├── src/
│ │ ├── config/ # Configuration files
│ │ ├── controllers/ # Request handlers
│ │ ├── middleware/ # Express middleware
│ │ ├── repositories/ # Database access layer
│ │ ├── routes/ # API route definitions
│ │ ├── services/ # Business logic
│ │ ├── utils/ # Utility functions
│ │ ├── app.ts # Express app setup
│ │ └── server.ts # Server entry point
│ ├── uploads/ # Uploaded files
│ ├── .env.example # Environment template
│ └── package.json
├── frontend/
│ ├── src/
│ │ ├── app/ # Next.js app directory
│ │ ├── components/ # React components
│ │ ├── hooks/ # Custom React hooks
│ │ └── services/ # API client
│ ├── public/ # Static assets
│ └── package.json
├── docs/
│ └── Architecture.md # Detailed architecture documentation
├── README.md
└── package.json
POST /api/auth/register- Register new userPOST /api/auth/login- Login userGET /api/auth/google- Google OAuth loginGET /api/auth/google/callback- Google OAuth callback
GET /api/videos- Get all videos (with optional filters)GET /api/videos/:id- Get single video by IDPOST /api/videos/upload- Upload video filePOST /api/videos/upload-url- Upload video by URLPATCH /api/videos/:id- Update video metadataDELETE /api/videos/:id- Delete videoPOST /api/videos/:id/like- Toggle like on video
GET /api/videos/:id/comments- Get video commentsPOST /api/videos/:id/comments- Add comment to video
POST /api/subscriptions/:channelId- Toggle subscription to channel
GET /api/users/:id- Get user profilePATCH /api/users/:id- Update user profile
GET /stream/videos/:filename- Stream video with HTTP 206 supportGET /stream/thumbnails/:filename- Serve thumbnail imagesGET /stream/avatars/:filename- Serve avatar images
cd backend
npm run dev # Start development server with hot reload
npm run build # Compile TypeScript to JavaScript
npm start # Start production server
npx prisma studio # Open Prisma Studio for database managementcd frontend
npm run dev # Start development server
npm run build # Build for production
npm start # Start production server
npm run lint # Run ESLint- Ensure PostgreSQL is running
- Verify DATABASE_URL in
.envmatches your PostgreSQL credentials - Check that the
videohubdatabase exists
- Change PORT in backend
.envfile - Change frontend port by modifying the dev script in
frontend/package.json
- Run
npx prisma generateafter schema changes - Run
npx prisma migrate devto apply schema changes to database
- Ensure
uploads/directory exists in backend - Check file size limits in Express configuration (default: 10MB)
ISC