π¬ UNWATCHED
Plex Discovery β Find what nobody has seen yet
Unwatched is a self-hosted dark-mode web app that cross-references your Radarr, Sonarr, and Tautulli libraries to surface movies and TV shows that one or more of your Plex users haven't watched yet.
β¨ Features
- Multi-user watch filtering β select one or more Plex users; only content unwatched by all selected users is returned
- Movies & TV shows β pulls your full Radarr and Sonarr libraries in one view
- Rich filters β genre, release year range, rating provider (TMDB / IMDb / Rotten Tomatoes / Metacritic / TVDB), content rating, runtime, and show status
- Sortable, filterable table β sort by title, year, popularity, rating, runtime, studio/network, or date added
- Detail drawer β click any row for a full metadata panel with ratings, runtime, trailer link, overview, and external links (IMDb, TMDB, TVDB)
- Persistent search state β filter selections are saved across page refreshes; only cleared when you hit Reset
- Collapsible sidebar β collapse the search panel for a full-width results view with a single click
- Poster images β proxied server-side so API keys are never exposed to the browser
- Dark mode β built on Ant Design v5 with a Plex-inspired dark theme throughout
- Cloudflare Access support β optional service token authentication for instances behind Cloudflare Zero Trust
- Single-container deployment β the production image serves the React frontend and Express API together
Deploy using the compose example below:
services:
unwatched:
image: ghcr.io/nrcom/unwatched:latest
container_name: unwatched
ports:
# Host port:container port. Change the left side if you want a different public port.
- "${APP_PORT:-3001}:3001"
environment:
# Required service URLs and API keys.
# Local IPs or hostnames can be used for services
# running on the same Docker network (e.g. http://192.168.1.100:7878 or http://radarr:7878)
TAUTULLI_API_KEY: ""
RADARR_URL: "https://radarr.example.com"
RADARR_API_KEY: ""
SONARR_URL: "https://sonarr.example.com"
SONARR_API_KEY: ""
# Public app settings. Keep APP_PORT aligned with the host port above.
APP_PORT: "3001"
APP_URL: "http://localhost:3001"
# Internal container settings. Most community users should leave these unchanged.
BACKEND_PORT: "3001"
BACKEND_PROXY_URL: "http://localhost:3001"
# Optional Cloudflare Access service token for protected Radarr/Sonarr/Tautulli instances.
# Leave blank if Cloudflare Access is not in use.
CF_ACCESS_CLIENT_ID: ""
CF_ACCESS_CLIENT_SECRET: ""
# Optional comma-separated Plex usernames to hide from the user selector.
EXCLUDED_PLEX_USERS: ""
restart: unless-stopped