CrossWatch (CW) tracks what you watch through Watcher and syncs your watchlists, ratings, history, playback progress and collections across supported media servers and trackers. Watcher doesn't need Plex Pass or Emby Premiere.
Set up multiple Watcher routes for your servers and users, and sync pairs between media servers, between trackers, or from a server to a tracker. CW runs locally, with a web UI and a CLI to manage it all.
⭐ Star this repository to get updates
Watcher doesn't need Plex Pass or Emby Premiere. Set up multiple routes for your servers and users, and send playback activity to their chosen supported destinations.
You can also keep media servers in sync with each other, connect them to trackers, or sync between trackers. Choose what each pair syncs: watch history, playback progress, watchlists, ratings or collections, depending on provider support. Run pairs manually or on a schedule.
Manage it all from one place: accounts, Watcher routes, syncs, current playback and a combined watchlist. Profiles keep your setup separate from those of friends and family.
Keep your data with you, without being tied to one tracker. Sync it across the services you use and keep local snapshots in the CW Tracker.
When you need more control, Interactive Sync lets you review changes before applying them. The Analyzer helps you check missing items, and saved mappings let you fix wrong matches, anime episode numbering, and split or combined episodes for future syncs.
- Watcher with multiple routes for different servers and users. No Plex Pass or Emby Premiere needed.
- Server-to-server, server-to-tracker and tracker-to-tracker sync, where supported.
- Watchlists, ratings, history, playback progress and collections. Rewatches too, for supported trackers.
- Multiple accounts, separate profiles and managed user support.
- Interactive Sync to review additions, updates and removals before applying them.
- Webhook scrobbling for supported providers.
- Custom mappings for wrong matches, anime IDs, and split or combined episodes.
- A local CW Tracker with snapshots of your server and tracker data.
CW works with Plex, Jellyfin, Emby, SIMKL, Floppy, FlickList, Trakt, WeTrakr, AniList, MyAnimeList (MAL), Kitsu, TMDb, MDBList, PublicMetaDB, PunchPlay, BingeBase, Scrob, Tautulli, Tracearr, Kodi, Nuvio, Stremio and its own local CW Tracker.
Not every integration supports every feature. Some sync lists and history; others report playback activity. Setup details are in the wiki.
The examples below use Docker. See the installation guide for more details.
Save this as compose.yaml:
services:
crosswatch:
image: ghcr.io/cenodude/crosswatch:latest
container_name: crosswatch
ports:
- "8787:8787"
environment:
TZ: Europe/Amsterdam
volumes:
- crosswatch_config:/config
restart: unless-stopped
volumes:
crosswatch_config:Change TZ to your timezone, then run this from the same folder:
docker compose up -dOr run it directly from Bash:
docker run -d \
--name crosswatch \
-p 8787:8787 \
-v crosswatch_config:/config \
-e TZ=Europe/Amsterdam \
--restart unless-stopped \
ghcr.io/cenodude/crosswatch:latestBoth examples store persistent data in a Docker volume mounted at /config. Keep that volume when replacing or updating the container.
Open http://localhost:8787. If Docker is running on another machine, use that machine's address with port 8787.
- Connect the accounts you want to use.
- Create a sync pair: choose which services to connect and what to sync.
- Run the pair and check the results. Use Interactive Sync if you'd like to review changes before applying them.
- Add a schedule if you want it to run automatically.
See the first-time setup guide for the full setup.
Watcher reports playback from Plex, Emby, Jellyfin, Kodi and Scrob to supported trackers. No Plex Pass or Emby Premiere needed for Watcher.
You can also use webhooks from Plex, Emby and Jellyfin. Anime ID mapping is available for Watcher and webhooks with supported providers.
The CrossWatch for Kodi add-on reports playback and household viewers. It also supports ratings directly in the add-on. Set up a Watcher route per viewer and they each get their own history, even when sharing a Kodi profile.
Sometimes the same episode has a different number on another service, or a title gets matched to the wrong movie. You can correct titles, IDs, seasons and episodes, then save the mapping for future syncs. Split and combined episodes are supported, and you can import or export your mappings.
Anime ID mapping, powered by AniBridge and animeApi, supports AniList, MyAnimeList, Kitsu, SIMKL and CW Tracker pairs.
Use the Analyzer when something hasn't synced as expected. You can compare snapshots, find missing items and watch time differences, fix wrong matches, check pending retries and release blocked items.
| Tool | What you can do |
|---|---|
| Editor | Inspect, add or block items, manage saved mappings, and handle split or combined episodes. |
| Sync topology advisor | See your sync routes and spot overlapping paths. |
| Playback Progress Manager | View and edit unfinished playback sessions across providers. |
| Import and Export | Import tracker files or export your data. |
| Events and Logs | Look through sync history, investigate problems, and filter logs by pair or run. |
| Captures | Roll back provider watchlists, ratings and history. |
There's also a unified watchlist, a player card showing what's playing, and notifications for sync progress and pending reviews. Schedules can be simple or configured per pair.
For Plex, you can import history for removed items into your CW Tracker.
Add -e CW_CLI_ONLY=1 to the Docker command, or CW_CLI_ONLY: "1" under environment in Compose. The API, CLI, webhooks and auth callbacks keep working.
For cron, Kubernetes CronJobs or another external scheduler, use run-once. Set up your accounts and sync pairs first:
docker run --rm \
-v crosswatch_config:/config \
-e TZ=Europe/Amsterdam \
ghcr.io/cenodude/crosswatch:latest \
run-onceUse the volume that contains your existing configuration. If you set up CW with Compose, its volume name normally includes the Compose project name; replace crosswatch_config above with that volume's actual name.
To run specific pairs, use their IDs, numbers or unique prefixes. Replace the example IDs below with your own:
docker run --rm \
-v crosswatch_config:/config \
ghcr.io/cenodude/crosswatch:latest \
run-once --pair pair_07c3 --pair pair_91abThe command exits with 0 on success and 1 if the sync reports errors or cancellation. Add --fail-on-unresolved if you also want unmatched items to fail the job.
Setup docs are in the wiki. For questions and discussion, there's r/CrossWatchApp.
Please report bugs in Issues, with steps to reproduce them and what went wrong.
Read CONTRIBUTING.md before sending a PR. For security reports, see SECURITY.md. The license is in LICENSE.
Every cent donated through Buy Me a Coffee goes directly to the ALS Foundation in the Netherlands.
Thanks to our sponsors for supporting CW.