DEV Community

Cover image for How I Built an Ultra-Fast Movie Discovery App with Next.js, Edge Runtime, and OpenAI
Nick Fasulo
Nick Fasulo

Posted on

How I Built an Ultra-Fast Movie Discovery App with Next.js, Edge Runtime, and OpenAI

The Problem

Finding something to watch shouldn't feel like a chore. Legacy movie sites are often weighed down by heavy ads, sluggish page transitions, and buried streaming links. I wanted a tool that got straight to the point: instant search, immediate streaming availability, and quick, objective AI synopses.

So, I solo-developed Galaxy Movies.

Live Demo: https://www.galaxymovies.app/

GitHub: https://github.com/NickFasulo/galaxy-movies

Key Features

Lightning-Fast Search: Browse thousands of titles and explore cast networks in a clean, cosmic dark-mode UI.

One-Click Streaming Check: Instantly view exact platform availability (where to stream, rent, or buy) without jumping through menus.

Instant AI Synopses: Concise, objective film overviews powered by OpenAI to give quick context before pressing play.

Dynamic OG Cards: Social share preview cards rendered on the fly with custom branding.

Tech Stack & Architecture Highlights

  • Frontend: Next.js (Pages Router) + Chakra UI
  • State & Data: React Query + TMDB API
  • Edge & AI Services: Vercel Edge Runtime (@vercel/og) + OpenAI API
  • Quality Assurance: Lighthouse CI
  1. Dynamic Social Cards on Vercel Edge Runtime: Built dynamic Open Graph image generation using @vercel/og. Requests parse title and poster data on Edge functions to serve custom social cards with sub-100ms response times.
  2. TMDB Image Optimization Bypass: Direct-to-CDN poster loading to bypass server image transformation limits while maintaining high performance.
  3. Automated Quality Checks: Integrated Lighthouse CI to enforce performance, accessibility, and SEO thresholds on builds.

Top comments (3)

Collapse
 
launchgatecheck profile image
Launch Gate •

The dynamic OG cards are a nice touch. Two things I'd check since both the cards and the synopses sit on paid or rate-limited calls:

  • Make sure the @vercel/og response has a long Cache-Control (e.g. public, s-maxage=86400, stale-while-revalidate=604800). Link unfurlers from Slack, Discord, X and iMessage each fetch the image, sometimes several times per paste. Without CDN caching every share re-renders the card and re-hits TMDB.
  • Store the AI synopsis per TMDB id (KV, or even a static JSON built at deploy for popular titles) instead of generating it per view. The synopsis of a 1994 film won't change, and it takes the OpenAI call off the page-load path, which helps the "ultra-fast" part too.

Did Lighthouse CI flag anything on the poster-heavy pages, like LCP from the first poster image?

Collapse
 
nickfasulo profile image
Nick Fasulo •

Great catches! Since then I've implemented these changes.

The OG route ships with s-maxage=604800, stale-while-revalidate=2592000 plus Vercel-CDN-Cache-Control, so unfurler re-fetches should never reach the function. There's a per-IP rate limit as a backstop, and ?poster= is locked to a TMDB-only pattern so it can't be used as an open image proxy. Fun bug I hit: TMDB serves webp on .jpg paths, which crashes Satori. Now the fetch checks content-type and falls back to a text-only card.

The synopsis is generated once per TMDB id into Redis with a 1-year TTL under a versioned key, with an in-memory LRU in front. Generation is capped globally and wrapped in a timeout during SSR. A miss just renders the page without that section. Crawlers never trigger generation, and their AI-less renders go out no-store so they can't poison the shared cache.

LCP was exactly what Lighthouse flagged. That's why the first row of posters and the detail backdrop get fetchPriority="high". CLS ended up as the hard gate since fixed-size poster frames make it easy

Collapse
 
nickfasulo profile image
Nick Fasulo •

Thanks for checking out Galaxy Movies! šŸš€

Drop a comment if you test it out on mobile or desktop. I’m hanging out in the comments to answer any technical questions about the architecture or feature requests!