- Overview
- Features
- Tech Stack
- Project Structure
- Getting Started
- Running Locally
- API Documentation
- Deployment
- Contributing
- License
S-Tube is a YouTube-inspired video sharing platform that allows users to upload, watch, like, comment on, and manage videos. Built with the PERN stack (PostgreSQL, Express, React, Node.js), it features a modern responsive UI and a robust RESTful API with JWT-based authentication, media uploads via Cloudinary, and real-time analytics.
- Upload videos with custom thumbnails
- Edit video title, description, and metadata
- Publish / unpublish videos
- Video view tracking
- Delete videos
- Register with avatar and cover image uploads
- Login / Logout with JWT-based sessions
- Token refresh mechanism
- Protected routes and API endpoints
- Dedicated video playback page
- Video metadata display (views, upload date, description)
- Like / Unlike toggle
- Comment system (add, view, delete)
- User channel pages with uploaded videos
- Subscribe / Unsubscribe to channels
- Subscription feed on the home page
- Channel analytics with charts (Recharts)
- Video performance metrics
- Upload management panel
- Video feed with all published content
- Search by video title
- Library with liked videos
- Subscription-based content filtering
- Responsive design (Tailwind CSS + DaisyUI)
- Toast notifications (react-hot-toast)
- Client-side routing (React Router)
- Loading states and error handling
| Technology | Purpose |
|---|---|
| React 19 | UI framework |
| Vite 8 | Build tool & dev server |
| Tailwind CSS 4 | Utility-first styling |
| DaisyUI 5 | UI component library |
| React Router 7 | Client-side routing |
| Axios | HTTP client |
| Recharts | Analytics charts |
| react-hot-toast | Toast notifications |
| Technology | Purpose |
|---|---|
| Node.js | Runtime |
| Express 5 | Web framework |
| Sequelize 6 | ORM |
| PostgreSQL | Database |
| Passport.js | Authentication |
| JWT (jsonwebtoken) | Token-based auth |
| Cloudinary | Media storage (videos, images) |
| Multer | File upload handling |
| bcryptjs | Password hashing |
| express-validator | Request validation |
s-tube/
├── client/ # React frontend
│ ├── public/
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ │ ├── Navbar.jsx
│ │ │ ├── VideoCard.jsx
│ │ │ └── DashboardChart.jsx
│ │ ├── context/ # Global state (AppContext)
│ │ │ └── AppContext.jsx
│ │ ├── pages/ # Route pages
│ │ │ ├── Home.jsx # Video feed
│ │ │ ├── Login.jsx # Authentication
│ │ │ ├── VideoPlayer.jsx # Video playback
│ │ │ ├── Channel.jsx # Channel page
│ │ │ ├── Dashboard.jsx # Creator analytics
│ │ │ ├── Upload.jsx # Video upload
│ │ │ ├── Videos.jsx # User's videos
│ │ │ ├── Edit.jsx # Edit video
│ │ │ ├── Library.jsx # Liked videos
│ │ │ └── Subscription.jsx # Subscriptions
│ │ ├── App.jsx
│ │ ├── main.jsx
│ │ └── index.css
│ ├── index.html
│ ├── vite.config.js
│ ├── tailwind.config.js
│ └── package.json
│
├── server/ # Express backend
│ ├── config/
│ │ ├── cloudinary.js # Cloudinary SDK
│ │ └── multer.js # File upload config
│ ├── controllers/
│ │ ├── auth.js # Auth endpoints
│ │ ├── video.js # Video CRUD
│ │ ├── like.js # Like/unlike
│ │ ├── comment.js # Comments
│ │ ├── subscriber.js # Subscriptions
│ │ └── analytics.js # Analytics data
│ ├── db/
│ │ └── sequelize.js # Database connection
│ ├── middleware/
│ │ ├── authmiddleware.js # JWT verification
│ │ └── validate.js # Validation handler
│ ├── models/
│ │ ├── User.js
│ │ ├── Video.js
│ │ ├── Like.js
│ │ ├── Comment.js
│ │ ├── Subscription.js
│ │ ├── Token.js
│ │ └── association.js # Model relationships
│ ├── routes/
│ │ ├── auth.js
│ │ ├── videos.js
│ │ ├── likes.js
│ │ ├── comments.js
│ │ ├── subscriptions.js
│ │ └── analytics.js
│ ├── index.js # Entry point
│ └── package.json
│
├── .gitignore
└── README.md
- Node.js v18+
- PostgreSQL 14+
- Cloudinary account (for media storage)
Clone the repository and install dependencies for both client and server:
git clone https://github.com/yourusername/s-tube.git
cd s-tube
# Install server dependencies
cd server
npm install
# Install client dependencies
cd ../client
npm installCreate a .env file in the server/ directory:
# Server
PORT=5000
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/s_tube
# JWT
JWT_SECRET=your_jwt_secret_key_here
JWT_REFRESH_SECRET=your_refresh_secret_key_here
# Cloudinary
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secretCreate a .env file in the client/ directory:
VITE_API_URL=http://localhost:5000Make sure PostgreSQL is running and create the database:
createdb s_tubecd server
npm startThe API will be available at http://localhost:5000.
cd client
npm run devThe app will be available at http://localhost:5173.
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /auth/register |
Register new user | No |
| POST | /auth/login |
Login user | No |
| POST | /auth/refresh-token |
Refresh JWT token | No |
| GET | /auth/profile/:id |
Get user profile | No |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /videos/upload |
Upload a video | Yes |
| GET | /videos/all-videos |
Get all videos | No |
| GET | /videos/my-videos |
Get user's videos | Yes |
| GET | /videos/:id |
Get video by ID | No |
| DELETE | /videos/:id |
Delete a video | Yes |
| PATCH | /videos/:id/update |
Update video metadata | Yes |
| PUT | /videos/:id/publish |
Toggle publish status | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /likes |
Like / unlike video | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /comments/:videoId |
Get video comments | No |
| POST | /comments/:videoId |
Add comment to video | Yes |
| DELETE | /comments/:id |
Delete a comment | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /subscriptions |
Subscribe / unsubscribe | Yes |
| GET | /subscriptions/mine |
Get user's subscriptions | Yes |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /analytics |
Get channel analytics | Yes |
The frontend is deployed on Vercel at s-tubefrontend.vercel.app.
# Build for production
cd client
npm run build
# Deploy to Vercel
npx vercel --prodThe API is deployed on Render at s-tube-x9l4.onrender.com.
Configure the following environment variables in your Render dashboard:
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
JWT_SECRET |
JWT signing secret |
JWT_REFRESH_SECRET |
JWT refresh secret |
CLOUDINARY_CLOUD_NAME |
Cloudinary cloud name |
CLOUDINARY_API_KEY |
Cloudinary API key |
CLOUDINARY_API_SECRET |
Cloudinary API secret |
The backend's server/index.js exports a default Express app, making it compatible with Vercel serverless functions as well.
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.
