A full-stack YouTube clone built with modern technologies. This project provides a complete video-sharing platform with user authentication, video uploads, and a responsive UI.
β Full-Stack Architecture - Frontend with Next.js and TypeScript, backend with Express and MongoDB
β User Authentication - Secure login and registration system with JWT
β Video Uploads - Drag-and-drop video uploads with metadata
β Responsive UI - Modern, clean interface using Mantine UI components
β Video Streaming - Efficient video playback with range requests
β Database Integration - MongoDB with TypeGoose for type-safe schema definition
β Password Hashing - Secure password storage with Argon2
β Real-time Notifications - Using Mantine Notifications for user feedback
β Search Functionality - Coming soon (roadmap)
β Video Recommendations - Coming soon (roadmap)
- Framework: Next.js 16 (App Router)
- Language: TypeScript
- UI Library: Mantine UI (v8)
- State Management: React Context API
- Styling: CSS
- Icons: Tabler Icons
- Framework: Express.js
- Database: MongoDB
- ORM: TypeGoose
- Authentication: JWT (JSON Web Tokens)
- Password Hashing: Argon2
- Validation: Zod
- Logging: Pino
- Build Tool: Webpack (via Next.js)
- Testing: Coming soon (Jest/React Testing Library)
- CI/CD: Coming soon (GitHub Actions)
Before you begin, ensure you have the following installed:
-
Clone the repository:
git clone https://github.com/David1DDT/youtube-clone.git cd youtube-clone -
Install dependencies:
# Install client dependencies cd client npm install # Install server dependencies cd ../server npm install
-
Set up environment variables: Create a
.envfile in both theclientandserverdirectories with the following variables:Client
.env:NEXT_PUBLIC_API_URL=http://localhost:4000
Server
.env:DB_CONNECTION_STRING=mongodb://localhost:27017/youtube-clone JWT_SECRET=your_jwt_secret_here CORS_ORIGIN=http://localhost:3000
-
Start the development servers:
# In a new terminal, start the server cd server npm dev # In another terminal, start the client cd ../client npm dev
-
Access the application: Open http://localhost:3000 in your browser.
-
Register a new account: Navigate to
/registerand fill in the registration form. -
Login: Use your credentials to log in at
/login. -
Upload a Video:
- Log in to access the upload button.
- Click the upload button in the header.
- Fill in the video details (title, description, public visibility).
- Drag and drop or select a video file.
-
View Videos:
- After uploading, your video will appear in the main feed.
- All public videos will be visible to everyone.
// Example of how the upload form works in the Upload.tsx component
const submitHandler = async (e: React.FormEvent) => {
e.preventDefault();
if (!fileRef.current?.files?.[0]) return;
const file = fileRef.current.files[0];
const formData = new FormData();
formData.append("file", file);
const response = await fetch("http://localhost:4000/api/videos", {
method: "POST",
body: formData,
credentials: "include",
});
if (!response.ok) throw new Error("Upload failed");
const data = await response.json();
console.log("Uploaded video:", data);
// Update video metadata
const updateVideoResponse = await fetch(
`http://localhost:4000/api/videos/${data.videoId}`,
{
method: "PATCH",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: titleRef.current?.value,
description: descriptionRef.current?.value,
published: publicRef.current?.checked,
}),
}
);
context?.toggle();
window.location.reload();
};// Example from video.controller.ts for streaming video chunks
export async function streamVideoHandler(req: Request, res: Response) {
const { videoId } = req.params;
const range = req.headers.range;
if (!videoId)
return res.status(StatusCodes.BAD_REQUEST).send("Invalid video Id");
const video = await findVideo(videoId);
if (!video) {
return res.status(StatusCodes.NOT_FOUND).send("Video not found");
}
const filePath = getPath({
videoId: video.videoId,
extension: video.extention,
});
const fileSize = fs.statSync(filePath).size;
const chunkSize = CHUNK_SIZE_IN_BYTES;
const start = parseInt(range.replace(/\D/g, ""));
const end = Math.min(start + chunkSize, fileSize - 1);
res.writeHead(StatusCodes.PARTIAL_CONTENT, {
"Content-Range": `bytes ${start}-${end}/${fileSize}`,
"Accept-Ranges": "bytes",
"Content-Length": end - start + 1,
"Content-Type": "video/mp4",
});
const fileStream = fs.createReadStream(filePath, { start, end });
fileStream.pipe(res);
}youtube-clone/
βββ client/ # Next.js frontend application
β βββ app/ # Next.js application routes
β β βββ (auth)/ # Authentication routes
β β β βββ login/ # Login page
β β β βββ register/ # Register page
β β βββ (main)/ # Main application routes
β β β βββ layout.tsx # Main layout
β β β βββ page.tsx # Home page
β β βββ components/ # Reusable components
β β β βββ Header.tsx # Main header component
β β β βββ Sidebar.tsx # Sidebar navigation
β β β βββ Upload.tsx # Video upload modal
β β β βββ VideoCard.tsx # Video card component
β β βββ globals.css # Global styles
β β βββ layout.tsx # Root layout
β βββ public/ # Static files
β βββ package.json # Client dependencies and scripts
β βββ tsconfig.json # TypeScript configuration
β
βββ server/ # Express backend application
β βββ src/ # Source files
β β βββ constants.ts # Application constants
β β βββ helpers/ # Helper functions
β β β βββ omit.ts # Object property omitting utility
β β βββ middleware/ # Express middleware
β β β βββ deserializeUser.ts # Deserialize user from JWT
β β β βββ requireUser.ts # Require user to be authenticated
β β βββ modules/ # Application modules
β β β βββ auth/ # Authentication module
β β β β βββ auth.controller.ts # Auth controllers
β β β β βββ auth.route.ts # Auth routes
β β β β βββ auth.schema.ts # Auth validation schemas
β β β β βββ auth.utils.ts # Auth utilities
β β β βββ user/ # User module
β β β β βββ user.controller.ts # User controllers
β β β β βββ user.model.ts # User model
β β β β βββ user.route.ts # User routes
β β β β βββ user.schema.ts # User validation schemas
β β β β βββ user.service.ts # User service functions
β β β βββ videos/ # Video module
β β β βββ video.controller.ts # Video controllers
β β β βββ video.model.ts # Video model
β β β βββ video.route.ts # Video routes
β β β βββ video.schema.ts # Video validation schemas
β β β βββ video.service.ts # Video service functions
β β βββ utils/ # Utility functions
β β β βββ database.ts # Database connection utilities
β β β βββ logger.ts # Logger configuration
β β βββ main.ts # Main application entry point
β βββ package.json # Server dependencies and scripts
β βββ tsconfig.json # TypeScript configuration
β
βββ .gitignore # Git ignore rules
βββ README.md # Project documentation
| Variable | Description | Default Value |
|---|---|---|
DB_CONNECTION_STRING |
MongoDB connection string | mongodb://localhost:27017/youtube-clone |
JWT_SECRET |
Secret key for JWT signing | your_jwt_secret_here |
CORS_ORIGIN |
Allowed origins for CORS (comma-separated) | http://localhost:3000 |
PORT |
Port for the Express server | 4000 |
-
Change UI Theme: Modify the Mantine theme configuration in
client/app/layout.tsxto change colors, fonts, and other UI elements. -
Add New Features:
- Extend the
video.schema.tsto add new video properties. - Add new routes in the respective modules (
auth,user,videos). - Implement new components in the
client/app/componentsdirectory.
- Extend the
-
Database Schema: Extend the
UserandVideomodels in their respective.model.tsfiles to add new fields.
We welcome contributions from the community! Here's how you can contribute to this project:
-
Fork the repository:
git clone https://github.com/David1DDT/youtube-clone.git cd youtube-clone -
Create a new branch:
git checkout -b feature/your-feature-name
-
Install dependencies:
# Client cd client npm install # Server cd ../server npm install
-
Start the development servers:
# Server cd server npm dev # Client cd ../client npm dev
- TypeScript: Use strict type checking and follow TypeScript best practices.
- ESLint: Follow the existing ESLint configuration for consistent code style.
- Commit Messages: Use conventional commit messages for better changelog generation.
- Naming Conventions:
- Use
camelCasefor variables and functions. - Use
PascalCasefor classes and components. - Use
UPPER_CASEfor constants.
- Use
- Write Tests: Add tests for new features or bug fixes.
- Document: Update the README or add comments to explain your changes.
- Submit PR: Open a pull request with a clear description of your changes.
- Review: Address any feedback from maintainers.
This project is licensed under the MIT License. See the LICENSE file for details.
- David Dumitru - Initial work and ongoing maintenance
If you encounter any problems or have feature requests, please open an issue on the GitHub Issues page. Include:
- A clear description of the issue or feature request.
- Steps to reproduce the issue (if applicable).
- Any relevant logs or error messages.
- Your environment details (Node.js version, MongoDB version, etc.).
Q: Can I use this for commercial purposes? A: Yes, this project is licensed under the MIT License, which allows for both personal and commercial use.
Q: How can I add a new feature? A: Start by creating a new branch and adding your feature. Make sure to write tests and update the documentation. Then submit a pull request.
- Search Functionality: Implement a search bar to find videos by title, description, or tags.
- Video Comments: Allow users to comment on videos.
- Video Likes: Enable users to like videos.
- User Profiles: Create detailed user profiles with upload history.
- Subscriptions: Allow users to subscribe to channels.
- Trending Algorithm: Implement a recommendation algorithm for trending videos.
- Video Playlists: Create and manage playlists.
- Mobile App: Develop a mobile application using React Native or Flutter.
- Video Thumbnails: Currently, thumbnails are not generated automatically. This will be addressed in a future update.
- Performance Optimization: Further optimization of video streaming and database queries is needed for large-scale deployment.
- Testing: Comprehensive test coverage is needed for critical components.
- Advanced Analytics: Add analytics for video views, engagement, and user behavior.
- Moderation Tools: Implement tools for content moderation and reporting.
- Monetization: Add features for monetizing videos through ads.
- Multi-language Support: Enable the application to support multiple languages.
- Search: Search videos in the application
Ready to dive in? Follow the installation steps and start building your own YouTube clone! Whether you're looking to learn new technologies, contribute to an open-source project, or simply explore a full-stack application, this project offers a great starting point.
Join our community, contribute, and let's build something amazing together! π

