Film Database
TL;DR: Built a movie trailer platform from scratch featuring a type-safe TMDB API wrapper with argument autocompletion, batch requests, response caching, and content filtering. Includes a custom YouTube iFrame solution, native JavaScript drag-and-drop collections, responsive carousels, polished SCSS-based animations, Firebase authentication with Firestore storage, and exploration of advanced TypeScript patterns with Vitest, Jest, and RTL testing.
Scope and Stack
This self-initiated movie database website was built using Vite, React, TypeScript, and styled with SASS. It integrates TheMovieDatabase (TMDB) API for movie data, React-YouTube for embedded video playback, and Firebase for authentication and full CRUD operations. Form validation is handled with Zod. Vitest was used for unit testing, and advanced TypeScript patterns were explored to ensure the codebase is developer-friendly.
Taming the TMDB API
TMDB presented several challenges: inconsistently formatted URLs, limited WEBP support, and adult content slipping through endpoint queries. To reduce API calls and prevent runtime errors, a type-safe API wrapper was built to handle endpoint construction, type inference, sessionStorage caching, and batch requests with Promise.allSettled. Content filtering was a head-scratcher: Since TMDB is an open platform where users contribute content, the 'adult' query parameter only partially filters results, requiring additional checks to keep content appropriate. Various options were considered, including region-locking, genre-based filtering, and rating restrictions. To further refine results, the naughty-words package was applied to titles and overviews, reducing adult content while remaining performant.
Covering the First Paint
To capture a polished feel similar to platforms like Netflix, a custom SCSS-driven loading screen (inspired by camillemormal's JavaScript variant) was created for initial load. It uses staggered animations, subtle transforms, and careful timing to produce a smooth reveal. Designing it required juggling scale effects and transition sequencing-a fun challenge that preserves performance. The loader integrates with React Router v7’s client loader, which prefetches carousel data, helping the UI feel immediately responsive.
A Double Helix Behind the Sign-In
The sign-in screen sits in front of a double-helix gallery, an effect inspired by Claude’s website. The geometry came from Hyperplexed’s video on the technique. Poster cards are mounted then transformed with rotateY and translateZ. A single value, progress along the strand, drives rotation, vertical travel, and depth together, which is what reads as a corkscrew instead of a rotating stack.
The order of that chain is what keeps it cheap. Rotating before translating means the translate runs in the frame the rotation just turned, so one constant radius places every card and no position is solved from sine and cosine. Rotation and vertical travel are then both linear in a card’s progress, which two keyframes reproduce exactly.
The result is pure CSS. Every card runs the same animations and differs only by a negative animation-delay, with nothing in JavaScript after mount. Brightness and blur come off the cosine, so shading runs as a second animation on the shorter rotation period. The form sits above it as a frosted panel.
Bending the YouTube Embed
For trailer playback, YouTube’s IFrame Player API was used in combination with the React-YouTube UI library to manipulate the player and match TMDB’s trailer data. The iFrame was stretched beyond its native aspect ratio, and a custom controller was built to replace the default YouTube UI, ensuring consistent positioning and styling across breakpoints and preserving the desired cinematic layout. Recommended videos appear when paused, a limitation of the embed.
A Carousel Sized in CSS
A major UI challenge was implementing a responsive carousel with dynamically sized items. Instead of relying on JavaScript-heavy solutions, CSS with viewport-based calculations and custom properties determined item dimensions. This approach was inspired by examining Amazon’s DOM for reference calculations, which were then adapted to fit the application's design. Computed styles were placed in context, allowing consumers-like the carousel and collections features-to dynamically and conditionally adjust. IntersectionObserver toggles data-attributes to manage display properties and fetch-priority hints, minimizing network load while keeping the carousel smooth and responsive.
Collections and Native Drag-and-Drop
Given the limitations of TMDB’s data, the only feasible feature was a collections page where users can organize movies into custom collections and queue trailers for sequential viewing. Drag-and-drop functionality was implemented natively, revealing the intricacies of drag events, state transitions, and race conditions. Firestore handles persistence and real-time updates. While full WAI-ARIA compliance isn’t achievable for draggable elements due to deprecation, interactions remain fluid and intuitive, preserving usability without compromising the learning experience. Due to data limitations, data visualization features weren't possible.
What It Taught
This project served as a comprehensive exercise in building scalable front-end architecture, refining CSS animations, and optimizing UI responsiveness across devices. Multiple rewrites deepened understanding of React patterns, performance trade-offs, and type-safe API design, culminating in a polished flagship project that balances developer ergonomics with user experience.



