Repolode
arabcoders

arabcoders/watchstate

Self-hosted service that syncs watch/play state between Plex, Jellyfin and Emby media servers without third-party services.

Stars
1,609
Forks
30
Open issues
2
Last commit
5 days ago

What is it?

WatchState keeps the play state of users (watched status and progress) consistent across Plex, Jellyfin and Emby media servers. It runs on your own infrastructure and does not depend on external sync services.

Sync can run in one-way or many-to-many mode between backends. Play state can also be exported into a portable format as a backup. Users are handled through identities, so several accounts on each server can be mapped to one another.

Updates arrive through webhooks from the media servers, or through scheduled and on-demand import tasks that catch anything webhooks miss. The project also includes a Media Health feature for finding record issues and a search over backend metadata. It ships as a Docker image with a web UI.

Key features

  • 01Syncs play state between Plex, Jellyfin and Emby, one-way or many-to-many.
  • 02Receives webhook events from media servers to update progress in near real time.
  • 03Exports play state into a portable backup format.
  • 04Supports multiple users through identities.
  • 05Includes Media Health checks for finding record issues.
  • 06Runs as a self-hosted Docker container with a web UI.

Use cases

  • Keeping watched status in sync when a household runs both Plex and Jellyfin.
  • Migrating or backing up watch history from a media server.
  • Avoiding sending viewing data to third-party sync services.

Quick start

  1. 1

    Create a compose.yaml with the WatchState service next to a data directory

  2. 2

    Start the container with Docker Compose

    mkdir -p ./data && docker compose up -d
  3. 3

    Open http://localhost:8080 and create a system user on first access

Things to know

  • Versions before 1.10.9 are affected by PHP runtime vulnerabilities, so update to 1.10.9 or later and recreate the container.
  • Existing records need a full import before they can match by path, since path matching is now on by default.
  • Podman users must set the container user to 0:0, and Unraid or permission issues may require adjusting the user ID.

In collections

Topics

FAQ

What is watchstate?
Self-hosted service that syncs watch/play state between Plex, Jellyfin and Emby media servers without third-party services. WatchState keeps the play state of users (watched status and progress) consistent across Plex, Jellyfin and Emby media servers. It runs on your own infrastructure and does not depend on external sync services.
Is watchstate free to use? What license does it have?
watchstate is open source under the MIT license. Check the license terms before using it in commercial products.
Is watchstate still maintained?
Actively maintained. The last commit to watchstate was on Nov 2, 2026.
What can I use watchstate for?
Keeping watched status in sync when a household runs both Plex and Jellyfin. Migrating or backing up watch history from a media server. Avoiding sending viewing data to third-party sync services.
How do I install watchstate?
Create a compose.yaml with the WatchState service next to a data directory Start the container with Docker Compose: mkdir -p ./data && docker compose up -d Open http://localhost:8080 and create a system user on first access
Where can I get watchstate?
The source code and installation instructions are on GitHub: https://github.com/arabcoders/watchstate

Summary generated by AI from the project's README. GitHub stats refresh daily.

Related projects