Skip to content
← All workCase 01 / 06

Lumora

Film & series discovery

Year
2023 — 26
Formerly the Netflix Clone
Built with
Next.js 16, React 19, TypeScript, Tailwind CSS 4 +8 more ↓
lumora-tanzim.vercel.app
Lumora — screenshot of the live site

(01) Overview

Lumora started life as a Netflix clone. I rebuilt it as a product of its own: browse what is trending, open any title to its official trailer, and keep a watchlist that follows you from device to device.

(02) Features

  1. 01Trailer-first heroA muted trailer fades in over the artwork once it is actually playing, and pauses when it scrolls out of view.
  2. 02Streamed catalogueRows stream in behind skeletons as their data arrives, with snap scrolling and hover previews.
  3. 03Title pagesCast, rating, certification and recommendations for every film and series.
  4. 04My ListSaved to Postgres against your account, with optimistic toggles so the button never waits on the network.
  5. 05Live searchResults update as you type, and the query lives in the URL so a search can be shared.
  6. 06Guest modeOne click into a shared demo account, alongside email and password sign-up.

(03) Screens

lumora-tanzim.vercel.app
Lumora — The landing page: a wall of posters behind the pitch
03.1The landing page: a wall of posters behind the pitch
lumora-tanzim.vercel.app
Lumora — A title page — artwork, rating, certification and the trailer
03.2A title page — artwork, rating, certification and the trailer
lumora-tanzim.vercel.app
Lumora — Search as you type; the query is kept in the URL
03.3Search as you type; the query is kept in the URL
lumora-tanzim.vercel.app
Lumora — Cast and recommendations further down a title
03.4Cast and recommendations further down a title

(04) On a phone

Same app, smaller screen.

Captured from the live site at 390 pixels wide — the width of most phones in a hand.

Lumora on a phone — Browse, with the tab bar
Browse, with the tab bar
Lumora on a phone — A title page
A title page

(05) Stack

Twelve tools, and the job each one does here.

  • FrameworkNext.js16App Router, Server Components and Server Actions
  • UIReact19useOptimistic keeps My List instant
  • LanguageTypeScriptTyped from the database schema to generated route types
  • StylingTailwind CSS4The whole interface, from tokens up
  • DataPostgreSQLAccounts and watchlists, with row-level security on
  • DataDrizzle ORMSchema, SQL migrations and Drizzle Studio
  • DataZodValidates the input of every Server Action
  • AuthNextAuthEmail and password, plus a one-click guest account
  • ServicesTMDB APICatalogue, cast, ratings and recommendations
  • ServicesYouTubeOfficial trailers, through the no-cookie player
  • UILucideIcons
  • HostingVercelProduction hosting

(06) Under the hood

  1. 01

    Catalogue data is fetched in Server Components and cached for an hour. The TMDB client is marked server-only, so the API token can never be bundled for the browser.

  2. 02

    Every write is a Server Action with its input parsed by Zod. Passwords are hashed with bcrypt and never stored or logged in plain text.

  3. 03

    Migrations switch on row-level security for every table, so a hosted Postgres such as Supabase cannot leak users through its public API.

  4. 04

    The hero trailer is skipped on small screens, with data saver on and for reduced motion. Focus states are visible throughout, and phones get a tab bar within reach of a thumb.

Next case

CryptoTracker