A Netflix-inspired movie and TV series recommendation platform built with Next.js 14, TypeScript, and Tailwind CSS. Features a cinematic sky-blue dark theme, content-based recommendation engine, commercial verdict analytics, and fluid motion-enhanced browsing experience powered by TMDB.
- Cinematic Hero Banner — Auto-rotating featured content with crossfade transitions and Ken Burns zoom effect
- Content Rails — Horizontal scrollable sections with scroll-triggered reveal animations
- Search & Filters — Full-text search with genre, year, rating, language, and sort filters
- Detail Pages — Rich movie/TV detail views with cast, trailers, keywords, metadata, and commercial verdict
- Commercial Verdict — Budget vs revenue analysis classifying titles as Blockbuster, Super Hit, Hit, Average, Flop, or Disaster with ROI metrics and animated progress bars
- Recommendation Engine — Content-based recommendations using genre similarity, quality scoring, and user preference weighting
- Watchlist — Persistent watchlist stored in localStorage
- Like/Dislike Feedback — Personalization signals that improve recommendations over time
- Browse by Genre — Genre-organized content discovery with 10 featured genres
- Fluid Motion — Framer Motion-powered page transitions, reveal animations, staggered content loading
- Sky Blue Theme — Premium dark cinematic base with cool blue accents throughout
- Responsive Design — Premium experience from mobile to desktop
- Loading States — Skeleton loaders and smooth transitions throughout
- Error Handling — Graceful error boundaries with helpful recovery actions
- Node.js 18+
- A free TMDB API key (get one here)
# Clone and install
git clone https://github.com/shauryadata/cineverse.git
cd cineverse
npm install
# Configure environment
cp .env.example .env.local
# Edit .env.local and add your TMDB API key
# Run development server
npm run devOpen http://localhost:3000 to view the app.
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Create production build |
npm run start |
Start production server |
npm run lint |
Run ESLint |
| Variable | Required | Description |
|---|---|---|
TMDB_API_KEY |
Yes | Your TMDB v3 API key |
TMDB_READ_ACCESS_TOKEN |
No | TMDB v4 read access token (optional) |
src/
├── app/ # Next.js App Router pages
│ ├── page.tsx # Homepage with hero + content rails
│ ├── search/ # Search with filters
│ ├── browse/ # Genre-based browsing
│ ├── watchlist/ # User watchlist
│ ├── movie/[id]/ # Movie detail page
│ ├── tv/[id]/ # TV show detail page
│ └── api/ # API routes
│ ├── search/ # Search & discover endpoint
│ ├── recommendations/ # Recommendation candidates
│ └── watchlist/ # Watchlist item resolver
├── components/
│ ├── home/ # HeroBanner, ContentRail, PersonalizedSection
│ ├── media/ # MediaCard, MediaGrid, MediaDetailView, VerdictCard
│ ├── search/ # SearchBar, FilterPanel
│ ├── layout/ # Navbar, Footer
│ └── ui/ # Button, Skeleton, RatingBadge, GenreBadge, MotionDiv
├── lib/
│ ├── tmdb.ts # TMDB API client (all data fetching)
│ ├── recommendations.ts # Recommendation engine
│ ├── verdict.ts # Commercial verdict classification logic
│ ├── types.ts # TypeScript domain models
│ └── utils.ts # Formatting & helper utilities
├── hooks/
│ ├── usePreferences.ts # Reactive user preferences hook
│ └── useDebounce.ts # Debounced value hook
└── store/
└── preferences.ts # localStorage-backed preference store
- Server/Client Split: Homepage content rails use React Server Components with Suspense boundaries for parallel streaming. Interactive features (watchlist, likes, search) are client components.
- API Layer: All TMDB calls go through
src/lib/tmdb.tswith consistent normalization. Internal API routes handle search aggregation and watchlist resolution. - No External State Library: User state is simple (lists of IDs + genre weights), so localStorage + a custom hook with event-based sync is sufficient.
- Image Optimization: Next.js
<Image>with TMDB CDN remote patterns for automatic optimization and lazy loading. - Motion Design: Framer Motion used for page transitions, scroll-triggered reveals, staggered animations, and interactive feedback — all subtle and performant.
Movie detail pages include an automated commercial performance classification based on budget and revenue data from TMDB.
The verdict is computed from the revenue-to-budget ratio, accounting for the industry standard that marketing costs are typically ~50% of production budget (so breakeven is ~2x):
| Verdict | Revenue / Budget | Description |
|---|---|---|
| Blockbuster | >= 4.0x | Massive commercial success |
| Super Hit | >= 3.0x | Strong box office performer |
| Hit | >= 2.0x | Profitable theatrical release |
| Average | >= 1.5x | Modest returns after marketing costs |
| Flop | >= 0.75x | Lost money at the box office |
| Disaster | < 0.75x | Significant financial loss |
- Budget and revenue figures
- Profit/loss amount
- ROI percentage
- Revenue-to-budget ratio with animated progress bar
- Color-coded verdict badge (emerald → green → sky → yellow → orange → red)
- Gracefully hidden when budget or revenue data is unavailable (common for older films, indie releases, or TV shows)
- TV shows do not display the verdict section (no budget/revenue data from TMDB)
The verdict logic lives in src/lib/verdict.ts and thresholds can be adjusted by modifying the ratio constants.
The recommendation system uses a content-based hybrid approach:
-
Genre Overlap (40%) — Weighted Jaccard similarity between item genres and user preference profile. Genre weights are built from like/dislike history.
-
Quality Signal (30%) — Bayesian-weighted average rating that accounts for vote count (prevents low-vote-count outliers from ranking too high).
-
Popularity Signal (15%) — Log-scaled popularity score to balance blockbusters vs. hidden gems.
-
Recency Boost (15%) — Time-decay function that gives newer content a slight edge.
- Like/Dislike feedback builds a genre weight profile over time
- Liked items boost their genres; disliked items penalize theirs
- Watchlisted items get a small score boost
- Previously rated items are excluded from recommendations
Each recommendation includes a contextual reason:
- "Because you enjoy Thriller"
- "Matches your taste in Sci-Fi"
- "Critically acclaimed"
- "Trending now"
On detail pages, recommendations use:
- TMDB's own similar/recommended endpoints
- Genre overlap with the current item
- "Similar in Drama & Crime" style labels
| Layer | Technology |
|---|---|
| Framework | Next.js 14 (App Router) |
| Language | TypeScript 5.5 |
| Styling | Tailwind CSS 3.4 |
| Animations | Framer Motion 11 |
| Icons | Lucide React |
| Data Source | TMDB API v3 |
| State | localStorage + custom hooks |
| Deployment | Vercel-ready |
- User Authentication — OAuth-based accounts with server-side preference persistence
- Collaborative Filtering — "Users who liked X also liked Y" using aggregated interaction data
- Semantic Search — Embedding-based search over movie descriptions for natural language queries
- Watch Providers — Integration with TMDB's watch provider data to show where titles are streaming
- Trailer Modal — Inline YouTube player instead of external redirect
- Infinite Scroll — Paginated loading for search results and browse pages
- PWA Support — Offline capability and installability
- Advanced Filters — Runtime range, decade picker, multi-genre selection, cast/crew search
- Social Features — Share lists, collaborative watchlists, friend recommendations
- AI-Powered Mood Matching — "I want something like Inception but more emotional" natural language recommendations
MIT