A shared family watchlist for movies and shows. One household queue: add what you want to watch, see where it is streaming, mark things watched so they drop off the list. The point of the build was to prove a personal media tracker can run at zero recurring cost without giving up sync across devices.
The Problem
A movie tracker normally reaches for a database. On the house stack that means Supabase, which is around $25 a month on the Pro tier for what is a personal toy. Paying a monthly fee to remember which shows the family wants to watch is the wrong trade. The watched state also has to sync across phones, which is exactly the part a local-only app cannot do.
What It Is
A static web app backed by two free APIs. Trakt holds the watchlist and watched history and already syncs across devices, so it serves as the database. TMDB supplies posters, metadata, and best-effort streaming availability. There is no application-owned datastore and no Supabase.
The one piece that cannot be fully static is OAuth: the Trakt token exchange needs a client secret, which must never ship to a browser. A single Cloudflare Pages Function handles that exchange server-side and proxies every API call, so no secret or token ever reaches the client. That keeps the whole thing on the Cloudflare free tier at $0.
How It Works
- One shared Trakt account for the household. One watchlist everyone sees and edits.
- All Trakt and TMDB traffic routes through
/api/*Pages Functions that attach credentials server-side. Tokens live in httpOnly cookies the browser cannot read. - Optimistic UI: add, mark-watched, and remove update the screen immediately and reconcile against Trakt in the background.
- Mobile-first, because the family uses phones.
Tradeoffs
- Streaming availability comes from TMDB, which is powered by JustWatch. It is region-locked and can be stale. It is a hint, not a guarantee, and attribution is required.
- v1 tracks one shared account, not per-person watched state. Per-person profiles are designed for later, not built.
- As of this writing the Trakt and TMDB calls are coded to the API docs but not yet run against live endpoints. No credentials are registered, so the request and response shapes are unverified. That is the one thing to prove before a deploy.
Stack
| Tool | Role |
|---|---|
| Trakt API | Backend of record: watchlist and watched history |
| TMDB API | Posters, metadata, streaming availability |
| Cloudflare Pages | Static hosting, free tier |
| Cloudflare Pages Functions | OAuth token exchange and API proxy, the only server-side component |
| React + Vite + TypeScript + Tailwind | Frontend |
Status
Scaffolded and building. Typecheck, production build, and tests pass locally. Not yet deployed: the next step is registering a Trakt app and a TMDB read token, then exercising the full login, search, add, and watched loop against the live APIs.