A full-stack movie database application built with React, Express.js, and MongoDB, powered by the TMDB API. Browse trending, popular, and top-rated movies & TV shows, manage your personal favorites and watchlist, and explore detailed cast & crew information — all wrapped in a modern, responsive UI.
- Trending Content — Discover trending movies and TV shows updated daily by TMDB
- Popular & Top Rated — Browse curated lists of popular and highest-rated movies
- Debounced Search — Search movies and TV shows instantly with optimized debounce logic
- Detailed Info Pages — View overview, rating, genres, runtime, and full cast & crew for any title
- User Authentication — Secure register and login system with JWT-based stateless authentication
- Favorites List — Save and manage your favorite movies and TV shows
- Watchlist — Keep track of content you plan to watch later
- User Profile — View personal stats, edit profile information, and change password
- Responsive Design — Fully responsive layout optimized for mobile, tablet, and desktop
- Backend Proxy — TMDB API key stays server-side, never exposed to the client
- Skeleton Loading — Smooth loading states with skeleton placeholders for better UX
- Star Rating Display — Visual star-based rating component for movie scores
- Route Protection — Guest-only and authenticated-only routes with automatic redirects
Screenshots will be added here.
- React 18: Modern UI library with hooks, context, and component-based architecture
- Vite 8: Next-generation build tool with lightning-fast HMR and optimized production builds
- Tailwind CSS 4: Utility-first CSS framework via the official Vite plugin
- React Router 6: Declarative client-side routing with nested layouts and route guards
- Axios: Promise-based HTTP client with interceptors for auth token injection
- React Hot Toast: Lightweight toast notification library for user feedback
- React Icons: Comprehensive icon library with tree-shaking support
- Node.js: Server-side JavaScript runtime environment
- Express 4: Minimal and flexible web application framework
- MongoDB (Mongoose 9): NoSQL database with elegant object modeling and schema validation
- JWT (jsonwebtoken): Stateless authentication with configurable token expiry
- bcryptjs 3: Secure password hashing with automatic salt generation
- Axios: Server-side HTTP client for proxying TMDB API requests
- Morgan: HTTP request logger for development debugging
- Node.js v18+ and npm
- MongoDB — MongoDB Atlas (free tier) or local instance
- TMDB API Key (free) — see Getting a TMDB API Key
- Go to themoviedb.org and create a free account.
- Navigate to Settings → API.
- Request an API key (choose the Developer option).
- Copy the API Key (v3 auth) value.
1. Clone the repository:
git clone https://github.com/Serkanbyx/s4.9_Movie-Database.git
cd s4.9_Movie-Database2. Set up environment variables:
cp server/.env.example server/.envserver/.env
PORT=5000
MONGODB_URI=mongodb://localhost:27017/moviedb
JWT_SECRET=your_jwt_secret_min_32_characters_here
JWT_EXPIRES_IN=30d
NODE_ENV=development
CLIENT_URL=http://localhost:5173
TMDB_API_KEY=your_tmdb_api_key_here
TMDB_BASE_URL=https://api.themoviedb.org/3client/.env.production (only needed for production builds)
VITE_API_URL=https://your-api-url.onrender.com/apiIn development, Vite's proxy forwards
/apirequests tohttp://localhost:5000automatically — no client.envfile needed.
3. Install dependencies:
cd server && npm install
cd ../client && npm install4. Run the application:
# Terminal 1 — Backend
cd server && npm run dev
# Terminal 2 — Frontend
cd client && npm run devThe client runs at http://localhost:5173 and the server at http://localhost:5000.
- Browse — Explore trending, popular, and top-rated movies on the home page
- Search — Use the search bar to find specific movies or TV shows
- Register — Create a new account with username, email, and password
- Login — Sign in to access personalized features
- Explore Details — Click on any title to view full details, ratings, and cast
- Favorites — Click the heart icon to add/remove movies from your favorites
- Watchlist — Click the bookmark icon to add/remove movies from your watchlist
- Profile — View your stats, update your profile info, or change your password
- Logout — Securely sign out from the navigation bar
The application uses JWT-based stateless authentication. On login or register, the server generates a signed JWT token that the client stores in localStorage. The Axios interceptor automatically attaches the token to every outgoing request via the Authorization: Bearer <token> header.
// Request interceptor — auto-attach JWT
api.interceptors.request.use((config) => {
const token = localStorage.getItem('token');
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
});On a 401 response, the interceptor clears the stored token and redirects the user to the login page.
All TMDB data flows through the Express backend as a proxy. The client never communicates directly with the TMDB API — this keeps the API key hidden and allows server-side rate limiting:
Client (React) → Express API (/api/movies/*) → TMDB API → Express → Client
User-specific data (favorites, watchlist, profile) is stored in MongoDB and accessed through authenticated API endpoints.
- Frontend: React with Context API for global auth state, custom hooks for reusable logic, and service modules for API abstraction
- Backend: MVC pattern with controllers, models, routes, middleware, and validators as separate layers
- Security: Multi-layered approach with Helmet, CORS, rate limiting, HPP, input validation, and body size limits
Interactive API documentation is available at
/api-docs(Swagger UI) when the server is running.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/auth/register |
No | Register a new user |
| POST | /api/auth/login |
No | Login and receive JWT |
| GET | /api/auth/me |
Yes | Get current user |
| PUT | /api/auth/profile |
Yes | Update profile |
| PUT | /api/auth/change-password |
Yes | Change password |
| DELETE | /api/auth/account |
Yes | Delete account |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/list/status/:movieId |
Yes | Check list status |
| GET | /api/list/:listType |
Yes | Get list items |
| POST | /api/list |
Yes | Add to list |
| DELETE | /api/list/:listType/:movieId |
Yes | Remove from list |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/movies/trending |
No | Trending movies & TV |
| GET | /api/movies/search |
No | Search movies & TV |
| GET | /api/movies/popular |
No | Popular movies |
| GET | /api/movies/top-rated |
No | Top rated movies |
| GET | /api/movies/:mediaType/:id |
No | Movie/TV details |
| GET | /api/movies/:mediaType/:id/credits |
No | Movie/TV credits |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/health |
No | Server health check |
Auth endpoints require
Authorization: Bearer <token>header.
s4.9_Movie Database/
├── client/ # React SPA (Vite)
│ ├── src/
│ │ ├── api/
│ │ │ └── axios.js # Axios instance & interceptors
│ │ ├── components/
│ │ │ ├── guards/
│ │ │ │ ├── GuestOnlyRoute.jsx
│ │ │ │ └── ProtectedRoute.jsx
│ │ │ ├── layout/
│ │ │ │ ├── Footer.jsx
│ │ │ │ ├── MainLayout.jsx
│ │ │ │ ├── Navbar.jsx
│ │ │ │ └── ScrollToTop.jsx
│ │ │ └── ui/
│ │ │ ├── CastCard.jsx
│ │ │ ├── ConfirmModal.jsx
│ │ │ ├── DetailPageSkeleton.jsx
│ │ │ ├── EmptyState.jsx
│ │ │ ├── ListButton.jsx
│ │ │ ├── MovieCard.jsx
│ │ │ ├── MovieCardSkeleton.jsx
│ │ │ ├── Pagination.jsx
│ │ │ ├── Spinner.jsx
│ │ │ └── StarRating.jsx
│ │ ├── contexts/
│ │ │ └── AuthContext.jsx # Global auth state management
│ │ ├── hooks/
│ │ │ ├── useAuth.js # Auth context consumer
│ │ │ ├── useDebounce.js # Debounce hook for search
│ │ │ └── useLocalStorage.js # localStorage sync hook
│ │ ├── pages/
│ │ │ ├── DetailPage.jsx
│ │ │ ├── FavoritesPage.jsx
│ │ │ ├── HomePage.jsx
│ │ │ ├── LoginPage.jsx
│ │ │ ├── NotFoundPage.jsx
│ │ │ ├── PopularPage.jsx
│ │ │ ├── ProfilePage.jsx
│ │ │ ├── RegisterPage.jsx
│ │ │ ├── SearchPage.jsx
│ │ │ ├── TopRatedPage.jsx
│ │ │ └── WatchlistPage.jsx
│ │ ├── services/
│ │ │ ├── authService.js # Auth API calls
│ │ │ ├── listService.js # Favorites & watchlist API calls
│ │ │ └── tmdbService.js # Movie & TV API calls
│ │ ├── utils/
│ │ │ ├── constants.js # App-wide constants
│ │ │ └── helpers.js # Utility functions
│ │ ├── App.jsx # Root component & routing
│ │ ├── main.jsx # Entry point
│ │ └── index.css # Global styles (Tailwind)
│ ├── index.html
│ ├── vite.config.js
│ └── package.json
│
├── server/ # Express REST API
│ ├── config/
│ │ ├── db.js # MongoDB connection
│ │ └── env.js # Environment variable validation
│ ├── controllers/
│ │ ├── authController.js # Auth route handlers
│ │ ├── listController.js # List route handlers
│ │ └── tmdbController.js # TMDB proxy handlers
│ ├── middlewares/
│ │ ├── auth.js # JWT protect middleware
│ │ ├── errorHandler.js # Global error handler
│ │ ├── rateLimiter.js # Rate limiting configs
│ │ └── validate.js # Request validation middleware
│ ├── models/
│ │ ├── MovieItem.js # Movie list item schema
│ │ └── User.js # User schema with password hashing
│ ├── routes/
│ │ ├── authRoutes.js # Auth endpoints
│ │ ├── listRoutes.js # List endpoints
│ │ └── tmdbRoutes.js # TMDB proxy endpoints
│ ├── utils/ # Token generation, TMDB client
│ ├── validators/
│ │ ├── authValidator.js # Auth input validation rules
│ │ └── listValidator.js # List input validation rules
│ ├── index.js # Server entry point
│ ├── package.json
│ └── .env.example # Environment template
│
├── README.md
└── .gitignore
- JWT Authentication — Stateless token-based authentication with configurable expiry and minimum 32-character secret enforcement in production
- Password Hashing — bcryptjs with automatic salt generation for secure password storage
- Helmet — Sets various HTTP security headers to protect against common attacks
- CORS — Restricted to allowed client origin with credentials support
- Rate Limiting — Three-tier rate limiting: global (100/15min), auth (10/15min), and TMDB (30/1min)
- HPP — HTTP Parameter Pollution protection against query string attacks
- Input Validation — express-validator on all user inputs with detailed field-level error responses
- Body Size Limit — Request body limited to 10KB to prevent payload abuse
- Backend Proxy — TMDB API key never exposed to the client browser
- Fingerprint Prevention —
x-powered-byheader disabled to hide server technology
-
Create a new Web Service on Render
-
Connect your GitHub repository
-
Set the following:
- Root Directory:
server - Build Command:
npm install - Start Command:
npm start
- Root Directory:
-
Add environment variables:
| Variable | Value |
|---|---|
PORT |
5000 |
MONGODB_URI |
Your MongoDB Atlas connection string |
JWT_SECRET |
A secure random string (min 32 chars) |
JWT_EXPIRES_IN |
30d |
NODE_ENV |
production |
CLIENT_URL |
https://movie-databasee.netlify.app |
TMDB_API_KEY |
Your TMDB API v3 key |
TMDB_BASE_URL |
https://api.themoviedb.org/3 |
-
Create a new site on Netlify
-
Connect your GitHub repository
-
Set the following:
- Base Directory:
client - Build Command:
npm run build - Publish Directory:
client/dist
- Base Directory:
-
Add environment variable:
| Variable | Value |
|---|---|
VITE_API_URL |
https://your-api-url.onrender.com/api |
The
public/_redirectsfile handles SPA routing on Netlify by redirecting all paths toindex.html.
- ✅ Browse trending, popular, and top-rated movies
- ✅ Search with debounced input
- ✅ Movie & TV show detail pages with cast
- ✅ JWT authentication (register, login, logout)
- ✅ Favorites and watchlist management
- ✅ User profile with stats and editing
- ✅ Password change functionality
- ✅ Account deletion
- ✅ Responsive design (mobile-first)
- ✅ Skeleton loading states
- ✅ Star rating component
- ✅ Pagination support
- ✅ Route guards (protected & guest-only)
- ✅ Toast notifications
- ✅ Backend proxy for TMDB API
- 🔮 [ ] TV show seasons and episodes detail view
- 🔮 [ ] User reviews and ratings
- 🔮 [ ] Social sharing functionality
- 🔮 [ ] Advanced filtering (by genre, year, rating)
- 🔮 [ ] Dark/light theme toggle
- 🔮 [ ] PWA support for offline access
- Fork the repository
- Create a feature branch:
git checkout -b feat/amazing-feature - Commit your changes:
git commit -m "feat: add amazing feature" - Push to the branch:
git push origin feat/amazing-feature - Open a Pull Request
| Prefix | Description |
|---|---|
feat: |
New feature |
fix: |
Bug fix |
refactor: |
Code refactoring |
docs: |
Documentation changes |
style: |
Code style changes (formatting) |
chore: |
Maintenance and dependency updates |
This project is licensed under the MIT License.
Serkanby
- Website: serkanbayraktar.com
- GitHub: @Serkanbyx
- Email: serkanbyx1@gmail.com
- TMDB API — Movie and TV show data provider
- React — UI library
- Vite — Build tool
- Tailwind CSS — CSS framework
- Express.js — Backend framework
- MongoDB Atlas — Cloud database
⭐ If you like this project, don't forget to give it a star!