A self-hosted dashboard that shows what's ready to watch across your Jellyfin, Sonarr, and Radarr media stack.
wtw syncs your media services on a schedule and evaluates each season and movie against configurable readiness rules — like requiring a complete season, a preferred audio language, or full monitoring in Sonarr — so you only see media that's actually ready to watch.
- Ready to Watch — series and movies that pass all your readiness checks
- Almost Ready — items close to meeting criteria with progress indicators
- Continue Watching — in-progress items based on Jellyfin watch history
- Language Overview — per-episode audio/subtitle language breakdown grid
- Detail Panel — rule results, episode status, and language info per item
- Search, Filter & Sort — find items by title, filter by type, sort by date or name
- Setup Wizard — guided first-run experience to connect your services from the browser
- Settings UI — configure rules, language targets, per-series overrides, and webhooks
- Discord & Webhook Notifications — get notified when media becomes ready
- Mobile-First — responsive layout with bottom tab bar and swipe gestures
Create a docker-compose.yml:
services:
wtw:
image: ghcr.io/1-felix/wtw:latest
container_name: wtw
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- wtw-config:/config
volumes:
wtw-config:docker compose up -dOpen http://localhost:3000 — the setup wizard will walk you through connecting Jellyfin, Sonarr, and Radarr. The first sync takes about 30 seconds.
The Docker image includes a built-in healthcheck on
/api/healthfor orchestrators like Portainer or Kubernetes.
Pre-configure with environment variables
If you prefer to skip the setup wizard, pass your service credentials as environment variables. These take priority over any values configured through the UI.
services:
wtw:
image: ghcr.io/1-felix/wtw:latest
container_name: wtw
restart: unless-stopped
ports:
- "3000:3000"
environment:
JELLYFIN_URL: "http://jellyfin:8096"
JELLYFIN_API_KEY: "your-jellyfin-api-key"
JELLYFIN_USER_ID: "your-jellyfin-user-id"
# Optional: Sonarr integration
# SONARR_URL: "http://sonarr:8989"
# SONARR_API_KEY: "your-sonarr-api-key"
# Optional: Radarr integration
# RADARR_URL: "http://radarr:7878"
# RADARR_API_KEY: "your-radarr-api-key"
# Optional: sync interval in minutes (default: 15)
# SYNC_INTERVAL_MINUTES: 15
volumes:
- wtw-config:/config
volumes:
wtw-config:Jellyfin is the only required service. Sonarr and Radarr are optional — when configured, they provide richer metadata that powers additional readiness rules (complete season, fully monitored).
Docker Run
docker run -d \
--name wtw \
-p 3000:3000 \
-v wtw-config:/config \
ghcr.io/1-felix/wtw:latestAll configuration is managed from the Settings page in the dashboard — rules, language targets, per-series overrides, notification webhooks, and service connections.
Settings, dismissed items, and notification history are persisted in a SQLite database at /config/wtw.db and survive container restarts.
- Node.js 22+
- pnpm
git clone https://github.com/1-Felix/wtw.git
cd wtw
pnpm install# Create .env.local with your service URLs and API keys
cp .env.example .env.local # edit with your values
pnpm devpnpm test # single run
pnpm test:watch # watch modedocker build -t wtw .
docker run -p 3000:3000 -v wtw-config:/config wtwMIT






