letβs build a simple YouTube-like clone using Node.js. Iβll walk you through the architecture, the backend (file upload + video streaming + REST APIs), a minimal frontend for uploading & playing videos, auth basics, and deployment tips. All code is copy-paste ready and focused on clarity and practicality you can extend features later (comments, search, recommendations, transcoding, CDN, etc.)
1. Setup
Install dependencies:
npm init -y
npm i express mongoose multer bcryptjs jsonwebtoken dotenv cors
Create folders:
youtube-clone/
ββ server.js
ββ routes/
β ββ auth.js
β ββ videos.js
ββ models/
β ββ User.js
β ββ Video.js
ββ public/
β ββ index.html
β ββ upload.html
β ββ player.html
ββ uploads/
.env
PORT=4000
MONGO_URI=mongodb://localhost:27017/youtube_clone
JWT_SECRET=secret
UPLOAD_DIR=uploads
2. Models
models/User.js
const mongoose=require('mongoose');
const bcrypt=require('bcryptjs');
const UserSchema=new mongoose.Schema({
name:String,email:String,passwordHash:String
});
UserSchema.methods.verifyPassword=function(p){return bcrypt.compare(p,this.passwordHash)};
module.exports=mongoose.model('User',UserSchema);
models/Video.js
const mongoose=require('mongoose');
const VideoSchema=new mongoose.Schema({
title:String,filename:String,mimeType:String,uploader:{type:mongoose.Schema.Types.ObjectId,ref:'User'},likes:{type:Number,default:0},views:{type:Number,default:0}
});
module.exports=mongoose.model('Video',VideoSchema);
3. Routes
Auth (routes/auth.js)
const express=require('express'),router=express.Router(),User=require('../models/User'),jwt=require('jsonwebtoken'),bcrypt=require('bcryptjs');
const secret=process.env.JWT_SECRET;
router.post('/signup',async(req,res)=>{
const {name,email,password}=req.body;
const hash=await bcrypt.hash(password,10);
const user=await User.create({name,email,passwordHash:hash});
const token=jwt.sign({id:user._id},secret);
res.json({token});
});
router.post('/login',async(req,res)=>{
const {email,password}=req.body;
const user=await User.findOne({email});
if(!user||!await user.verifyPassword(password))return res.status(401).json({error:'Invalid'});
const token=jwt.sign({id:user._id},secret);
res.json({token});
});
module.exports=router;
*Video *(routes/videos.js)
const
express=require('express'),router=express.Router(),multer=require('multer'),fs=require('fs'),path=require('path'),Video=require('../models/Video');
const upload=multer({dest:'uploads/'});
router.post('/upload',upload.single('video'),async(req,res)=>{
const v=await Video.create({title:req.body.title,filename:req.file.filename,mimeType:req.file.mimetype});
res.json(v);
});
router.get('/',async(req,res)=>res.json(await Video.find()));
router.get('/:id/stream',async(req,res)=>{
const v=await Video.findById(req.params.id);
const file=path.join('uploads',v.filename);
const stat=fs.statSync(file);const range=req.headers.range;
if(range){const [start,end]=range.replace(/bytes=/,'').split('-').map(Number);
const s=start,e=end||stat.size-1;const chunk=e-s+1;
res.writeHead(206,{'Content-Range':`bytes ${s}-${e}/${stat.size}`,'Accept-Ranges':'bytes','Content-Length':chunk,'Content-Type':v.mimeType});
fs.createReadStream(file,{start:s,end:e}).pipe(res);}else{
res.writeHead(200,{'Content-Length':stat.size,'Content-Type':v.mimeType});
fs.createReadStream(file).pipe(res);
}});
module.exports=router;
If you want to download youtube video in your gallary download Snaptube apk.
4. Server Setup
server.js
require('dotenv').config();
const express=require('express'),mongoose=require('mongoose'),cors=require('cors'),path=require('path');
const auth=require('./routes/auth'),videos=require('./routes/videos');
const app=express();
app.use(cors());app.use(express.json());
app.use('/api/auth',auth);
app.use('/api/videos',videos);
app.use(express.static('public'));
mongoose.connect(process.env.MONGO_URI).then(()=>app.listen(4000));
5. Frontend (simplified)
public/index.html
<h1>YouTube Clone</h1>
<a href="/upload.html">Upload Video</a>
<div id="list"></div>
<script>
fetch('/api/videos').then(r=>r.json()).then(vs=>{
document.getElementById('list').innerHTML=vs.map(v=>`<p>${v.title} - <a href="player.html?id=${v._id}">Play</a></p>`).join('');
});
</script>
public/player.html
<video id="v" controls></video>
<script>
const id=new URLSearchParams(location.search).get('id');
document.getElementById('v').src=`/api/videos/${id}/stream`;
</script>
Final Words
Building a YouTube clone with Node.js is a great way to understand how modern video platforms work behind the scenes. This project demonstrates how file uploads, video streaming, and API-based architectures come together to create a functional media service.
While this version covers the basics, you can enhance it further by adding user authentication, thumbnails, comments, search functionality, and cloud storage support. With each improvement, youβll get closer to a professional-level streaming platform β and strengthen your full-stack development skills in the process.
gg
Top comments (0)