A self-hosted home for your shared watchlist. Track, pick, and plan what to watch with friends — with Plex, Letterboxd, and Radarr integration for home media server users.
- Why Screened?
- Features
- Screenshots
- Quick Start
- Documentation
- Getting Help
- Contributing
- Tech Stack
- Development
Most tracking apps are built for solo use. Letterboxd is great for logging what you've watched, but there's no way to build a list with friends. Tools like Watcharr add collaborative lists, but the list lives in a silo — it can't drive your download client or help you actually decide what to watch next.
Screened was built to close that gap: a shared watchlist that feeds your Picker, your Watch Parties, and — for home server users — your Radarr queue automatically.
- Collaborative lists — shared watchlists with member invites; each list exports a live Radarr endpoint for home media server users
- Movie Night Picker — collaborative "what should we watch?" sessions with reference-title scoring
- Watch Parties — schedule viewings and invite friends; everyone gets notified and can RSVP
- Personal tracking — watchlist, watching, watched, dropped status with star ratings and reviews
- Episode tracking — per-episode progress for TV shows with notes and watch timestamps
- Plex sync — import your watch history automatically; manual and scheduled sync supported
- Letterboxd — connect your public profile to import diary entries and ratings
- Watch history — unified log across Plex, Letterboxd, and manual entries with a calendar view
- Discord integration — channel webhooks, slash commands, and DM notifications (optional)
curl -o .env https://raw.githubusercontent.com/jamiebclark/screened/main/.env.example
curl -o docker-compose.yml https://raw.githubusercontent.com/jamiebclark/screened/main/docker-compose.yml
# edit .env — set TMDB_API_KEY, AUTH_SECRET, NEXTAUTH_URL, NEXT_PUBLIC_APP_URL
docker compose up -dThe app will be available at http://localhost:3000 (or whatever PORT you set in .env). The first user to register gets admin access.
→ Full deployment guide — env var reference, sync scheduling, backup & restore, manual setup
| Guide | Audience |
|---|---|
| Deployment | Docker Compose, env vars, manual setup |
| Plex | Connecting your Plex account and syncing watch history |
| Letterboxd | Importing your diary and ratings |
| Lists & Radarr | Collaborative lists and auto-downloading via Radarr |
| Movie Night Picker | How the Picker and scoring work |
| Watch Parties | Scheduling and inviting friends to watch together |
| Discord | Webhooks, slash commands, and DM notifications |
- GitHub Discussions — questions, ideas, and general conversation
- GitHub Issues — bug reports and feature requests only
Contributions are welcome. See CONTRIBUTING.md for local dev setup, commit conventions, and the PR checklist.
| Layer | Technology |
|---|---|
| Framework | Next.js (App Router) + TypeScript |
| Styling | Tailwind CSS v4 + Radix UI |
| Database | PostgreSQL + Prisma |
| Auth | Auth.js v5 (credentials + Plex OAuth) |
| Metadata | TMDB API |
| Deployment | Docker Compose |
| Command | Description |
|---|---|
yarn dev |
Start development server |
yarn build |
Build for production |
yarn lint |
Run ESLint |
yarn db:migrate |
Run Prisma migrations |
yarn test:e2e |
Playwright end-to-end tests |
yarn db:studio |
Open Prisma Studio (database GUI) |
yarn db:generate |
Regenerate Prisma client |
src/
├── app/
│ ├── (auth)/ # Login and register
│ ├── (app)/ # App shell: home, search, pick, watchlists, lists, movies, TV, settings, history, …
│ └── api/ # Route handlers (media, lists, plex, letterboxd, picker, cron, auth, …)
├── components/ # Feature UI and components/ui (Radix + Tailwind)
├── generated/ # Prisma client output (from prisma/schema.prisma)
└── lib/ # auth, prisma, tmdb, plex, letterboxd, embeddings, picker state, etc.
Prisma schema and migrations live under prisma/; the generated client is written to src/generated/prisma (not committed).
This project uses Conventional Commits. Releases and changelogs are automated via semantic-release.
feat(lists): add CSV import for watchlists
fix(plex): handle expired tokens gracefully
docs: update Radarr setup instructions



