Already running Plex and thinking about switching to Jellyfin? You don’t have to re-rip anything or move any media. Both point at the same folder on the same NAS. What actually needs migrating is your watch history: what’s been watched, what’s in progress, and your ratings. This covers that, using a tool built for exactly this job.

Step 1. Install Jellyfin first, pointed at the same media folder
If you haven’t already, follow the Jellyfin install guide and map it to the exact same /volume1/media path Plex is using. Let Jellyfin finish its library scan before moving on. The sync tool matches items by filename and metadata provider ID, so both servers need to know about the same files first.
Step 2. Get a Plex token
Open Plex Web, play any item, then ⋮ menu → Get Info → View XML. The URL that opens contains X-Plex-Token= followed by your token. Copy everything after the equals sign. This is Plex’s own documented way to find it, no third-party tool needed.
Step 3. Get a Jellyfin API key
In Jellyfin, go to Dashboard → API Keys → +, name it something like jellyplex-sync, and copy the generated key.
Step 4. Set up JellyPlex-Watched
Make a docker/jellyplex-watched folder, and inside it a .env file:
PLEX_BASEURL=http://YOUR_NAS_IP:32400
PLEX_TOKEN=your-plex-token-from-step-2
JELLYFIN_BASEURL=http://YOUR_NAS_IP:8096
JELLYFIN_TOKEN=your-jellyfin-api-key-from-step-3
SYNC_INTERVAL=60
DRYRUN=True
Then in Container Manager → Project → Create, point it at that folder with this compose file:
services:
jellyplex-watched:
image: luigi311/jellyplex-watched:latest
container_name: jellyplex-watched
env_file: .env
restart: unless-stopped
DRYRUN=True makes the tool log what it would sync without changing anything in Jellyfin. Deploy it this way first and read the container logs. Confirm it’s matching your actual titles before you let it write.Step 5. Go live
Once the dry run looks right, meaning real titles, sensible matches, and no wall of “no match found” errors, edit .env to DRYRUN=False and redeploy. With SYNC_INTERVAL=60 it re-syncs every 60 minutes, which is plenty to keep both servers agreeing on watch state while you run them side by side.
Step 6. Decide how long to run both
No rush to cut Plex off. Keep both running against the same media folder with the sync tool bridging watch state, for however long it takes everyone in the house to actually switch. When you’re ready, stop the Plex container and remove the sync tool. The media files are untouched either way.
A full migration without touching a single media file or losing years of watch history. The only thing that moved was metadata.