Plex to Jellyfin Migration: Libraries and Watch History
Doc-based, not yet hands-on tested. This guide is written from the official documentation and has not yet been tested hands-on by us. Check the current official docs before running anything.
Versions/date: Jellyfin Server v12.3 (confirmed in our factcheck report — https://github.com/jellyfin/jellyfin/releases/tag/v12.3). Watch-status script: wilmardo/migrate-plex-to-jellyfin, which has no releases, so we reference commit
089b1ebf9077(2026-07-09 23:17 JST). Last checked: 2026-10-24.
Transparency note (HomelabWise): This guide is based on official documentation only and was not hands-on tested by us. Check the linked docs before you run anything.
What can and can't move
From Jellyfin's Migrating page:
- "Jellyfins internal databases cannot be copied or adjusted easily." There is no official Plex database import.
- Watched status and users: "There are third-party scripts available that will use the API to copy watched status and users from one instance to another. This can be done from Plex, Emby or another Jellyfin instance." The page links the Plex script used below. Note: the specific Plex script below only copies watched status; it does not create or copy users (it requires an existing Jellyfin user via
--jellyfin-user, per its README andmigrate.pyat commit089b1ebf9077). - Your media files stay where they are. Jellyfin reads the same folders, so nothing needs to be copied.
Step 1 — Keep Plex running and back it up
Don't uninstall Plex until Jellyfin is working and the watch history has been copied. The script reads from your live Plex server.
Step 2 — Install Jellyfin and point it at the same media
Install Jellyfin v12.3 (for Docker with Intel hardware acceleration, see our Quick Sync guide). Mount your media folders read-only if you want extra safety:
volumes:
- <MEDIA_DIR>:/media:ro # same files Plex uses; ":ro" prevents writes*(:ro is standard Docker Compose syntax, not from the Jellyfin migration page.)*
Jellyfin expects its own folder layout. For movies, the docs say they "should be organized into individual folders for each movie", for example Movies/Best_Movie_Ever (2019)/Best_Movie_Ever (2019).mp4 (Movies docs). If your Plex library uses a different layout, some items may not match. Fix the names before migrating watch status, because the script matches by file name.
Step 3 — Recreate users
Users are not migrated. The watch-status script does not copy users, so you have to recreate each user by hand in Jellyfin before you run it.
Create a Jellyfin user for each Plex user in the Jellyfin Dashboard. The script won't do this for you. The script needs the Jellyfin user name (--jellyfin-user).
Step 4 — Copy watched status (third-party script)
⚠️ Caution: this script is community-maintained, marked "WIP" in its README, and has no license file or releases. It writes to your Jellyfin server and needs your Plex token and a Jellyfin API key. Both grant broad access, so treat them like passwords. Always use
--dry-runfirst, and delete the Jellyfin API key afterwards.
Tokens: the README links Plex's guide to finding your X-Plex-Token. Create the Jellyfin key under Dashboard > API Keys.
Install (from the README):
git clone https://github.com/wilmardo/migrate-plex-to-jellyfin.git
cd migrate-plex-to-jellyfin
git checkout 089b1ebf9077 # optional: the commit this guide references
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt*(The git clone/checkout lines are ours. The README starts at the venv step.)*
Dry run (README options; placeholders are ours):
python3 migrate.py --dry-run --debug \
--plex-url https://<PLEX_HOST>:32400 --plex-token <YOUR_PLEX_TOKEN> \
--jellyfin-url https://<JELLYFIN_HOST> --jellyfin-token <YOUR_JELLYFIN_API_KEY> \
--jellyfin-user <JELLYFIN_USER>Useful README options:
--plex-managed-user <NAME>: migrate a Plex managed user.--translate <PLEX_PATH>:<JELLYFIN_PATH>: use this when the two servers see the media under different paths. Translations "only happen at the beginning of the path".--skip: "Skip when no match it found instead of exiting".--secure / --insecure: verify SSL or not. The README examples use--insecure, but prefer--securewhen you have valid certificates.
When the dry-run output looks right, run the same command without --dry-run. Repeat it for each user.
Step 5 — Apps
Install the Jellyfin client for each device from the official downloads page. Plex apps won't connect to Jellyfin.
Sources
- https://jellyfin.org/docs/general/administration/migrate
- https://jellyfin.org/docs/general/server/media/movies
- https://github.com/wilmardo/migrate-plex-to-jellyfin (README, commit 089b1ebf9077)
- https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/
- https://github.com/jellyfin/jellyfin/releases/tag/v12.3