Franchisarr looks at your Plex, Jellyfin or Emby library and finds two things you probably want and don't have:
- Films missing from collections you already own part of. You have Beverly Hills Cop and II but not III — one click sends it to Radarr.
- Spin-offs of shows you already watch. You have NCIS but not NCIS: Los Angeles — one click sends it to Sonarr. Found through Wikidata, so it also knows Family Guy → American Dad!, which no name search could — and crosses between film and TV: own the film Serenity and it suggests the series Firefly.
Every list can be sorted — pick what to sort by from the dropdown, and flip the direction with the button beside it ("↓ Most first", "A → Z") — and each page remembers your last choice on your account, so it follows you between devices.
And, built on the same data: franchise pages that put films and TV together (Star Wars — you have 8 of 15; fan films are left out), director pages (you own 11 Nolan films; missing Following and Insomnia), an Upcoming page of announced films in franchises you own — as a list or a month-by-month calendar — with release-date notifications, import lists Radarr and Sonarr can poll so you never have to click Add, and playlists of a franchise, collection or director in release order — or in story order — on Plex, Jellyfin or Emby — films and episodes together, so a franchise plays the way it came out.
It reads all three — one of them or several at once, with a film on any of them counting as owned and a tick on what you've watched — supports multiple Radarr and Sonarr instances, signs you in with your media-server account, scans on a schedule, tells you when it finds something new — Discord, Slack, or anything Apprise reaches (Telegram, Pushover, ntfy, email, a hundred more) — wears your theme.park theme like the rest of your stack, and has a web UI and a CLI. Everything it hides — low-rated films, TV films and specials, shorts, directors' music-video collections — is folded away rather than deleted, and most of it is a preference.
Franchisarr owes its starting idea to Gaps, which has found missing collection films in Plex since 2019. This is that idea extended to Jellyfin and Emby, to TV spin-offs and cross-media franchises, and to import lists the *arrs poll themselves.
Status: pre-1.0 and in daily use against a real library of ~3,400 films and ~660 shows. Images are published to GHCR for amd64 and arm64.
How it was built: largely written by Claude Code, Anthropic's AI coding tool — directed, tested against a real library and reviewed by a human. The core — matching, gaps, spin-offs, franchises, directors — was measured against that library as it was built (the numbers are in the changelog); what hasn't been tested for real is listed under What's been tested. There are over 1,100 tests with no live network calls, and the full git history was scanned for secrets before the repo went public. The code is MIT; read it.
| Collection detail | Franchise |
|---|---|
![]() |
![]() |
| TV spin-offs | Directors |
|---|---|
![]() |
![]() |
mkdir franchisarr && cd franchisarr
curl -fsSLO https://raw.githubusercontent.com/prophetizer/franchisarr/master/docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/prophetizer/franchisarr/master/.env.example -o .env
# edit .env — at minimum: your media server (PLEX_URL+PLEX_TOKEN, or JELLYFIN_URL+JELLYFIN_API_KEY,
# or EMBY_URL+EMBY_API_KEY), TMDB_API_KEY, ADMIN_USERNAME, ADMIN_PASSWORD
docker compose up -dThe image is ghcr.io/prophetizer/franchisarr (latest, or a version like 0.76.0). To build
from source instead, clone the repository and change image: to build: . in the compose file.
Then open http://localhost:8000, sign in, choose which libraries to scan, and run a scan.
You need a TMDb API key — the free v3 one from themoviedb.org/settings/api. Note it's the shorter value on that page; the v4 Read Access Token won't work, and Franchisarr will tell you so if you paste it by mistake.
Coming, after more testing. A Community Applications template is drafted in
contrib/unraid/, but it hasn't been run on Unraid yet, so it isn't
recommended. Until then it runs on Unraid like any other container: image
ghcr.io/prophetizer/franchisarr, port 8000, a path mapped to /config, and the environment
variables from the Configuration table below.
Almost everything can be set in the app itself — media servers under Servers, Radarr, Sonarr and Seerr under Instances, the rest under Settings. Environment variables are a convenience for docker-compose, and they behave in one of two ways:
- Seeded once: media servers, Radarr, Sonarr, the admin account, and the values Settings
owns (TMDb and fanart.tv keys, schedule, notifications). Read on first boot only; after that
the database wins, so change them in the app. The exception is
TMDB_API_KEY: while no key is saved it's read at every start, so adding it to.envlater and restarting works. The log names any other.envvalue that's being ignored. - Read every start:
BASE_URL,TZ,PUID/PGID,LOG_LEVEL,SESSION_COOKIE_SECURE,TRUSTED_PROXY_HOPS,SHOW_ARTWORK, theTP_*theme variables andUPDATE_CHECK. Change these and restart.
See .env.example for the full list.
| Variable | Purpose |
|---|---|
PLEX_URL, PLEX_TOKEN |
Your Plex server |
JELLYFIN_URL, JELLYFIN_API_KEY |
Your Jellyfin server (Dashboard → API Keys) |
EMBY_URL, EMBY_API_KEY |
Your Emby server |
MEDIA_SERVER |
Optional: seed only plex, jellyfin or emby when several pairs are set |
TMDB_API_KEY |
Your own free v3 key |
FANART_API_KEY |
Optional; adds franchise logos to collection headings |
SHOW_ARTWORK |
false turns off all poster and logo images |
RADARR_URL, RADARR_API_KEY |
Optional first Radarr; more can be added in the UI |
SONARR_URL, SONARR_API_KEY |
Optional first Sonarr |
ADMIN_USERNAME, ADMIN_PASSWORD |
Fallback login, created on first boot only |
BASE_URL |
e.g. /franchisarr when behind a reverse proxy subpath |
SCAN_SCHEDULE_CRON |
e.g. 0 3 * * *; empty disables scheduled scans |
TZ |
Which timezone the schedule runs in |
PUID, PGID |
Ownership of the config volume, as in the linuxserver.io images |
TRUSTED_PROXY_HOPS |
Reverse proxies in front of the app (default 1; 2 behind Cloudflare's proxy plus Traefik). Lets the sign-in rate limit see visitors' real addresses |
Spin-offs of shows you own are discovered from Wikidata during a scan — no key or account needed — and matched on TMDb ids rather than titles, so it finds the ones whose names give nothing away (Family Guy → American Dad!). Weaker evidence is marked possible, and nothing is ever added without you clicking. If you think one has been missed, Search a single show on the Spin-offs page looks on TMDb for shows named after it (NCIS → NCIS: Sydney), leaving out official podcasts and making-of documentaries.
Rather than clicking Add per film, let the *arrs pull from Franchisarr. Under Settings → Import lists, generate a key (Settings is for administrators); then in Radarr, Settings → Import Lists → Add → Custom List and paste a films URL, for example:
https://franchisarr.example.com/api/lists/films.json?api_key=YOUR_KEY&min_rating=7
Sonarr takes the shows URL the same way. The key is shown once, stored only as a hash, and can be
revoked from the same place. Radarr's and Sonarr's own settings then decide what
to monitor and where — Franchisarr never adds anything itself. Your dismissals and preferences apply to the
lists; min_rating on the URL overrides the household floor for that list only.
Collection screens show posters from TMDb. Adding a free fanart.tv key additionally puts the franchise wordmark over a backdrop at the top of each collection — the only thing that key is used for.
Both are fetched by the browser from image.tmdb.org and assets.fanart.tv, so a client with no
internet access, or anyone who would rather nothing left their network, can set
SHOW_ARTWORK=false for a text-only interface.
Use their address on your own network, not a public one:
services:
franchisarr:
networks: [arrs] # the network Radarr and Sonarr are already on
networks:
arrs:
external: trueRADARR_URL=http://radarr:7878
SONARR_URL=http://sonarr:8989
A public URL behind a login proxy — Authelia, Authentik, Cloudflare Access — will not work:
those answer API requests with a login page, and an API key can't get past one. Franchisarr says
so rather than blaming your API key. If you'd rather keep the public URL, add a bypass rule in
the proxy for /api so API-key requests are let through.
If your household routes requests through Seerr — or the Overseerr or Jellyseerr it grew out of — add it on the Instances page, with the API key from Seerr's own Settings → General. Every Add dialog then offers Request via Seerr next to the direct Radarr/Sonarr choice: Seerr picks the *arr, profile and folder from its own settings, and the request shows up in Seerr's history like any other. Open requests keep a title out of the lists the way a queued Radarr add does; declined and failed ones come back, since those are worth asking again.
One thing to know: Seerr's API key acts as its administrator, and administrators' requests are approved automatically. So a request made from Franchisarr normally goes straight through rather than waiting for someone to approve it — the result in the dialog says which happened.
In February 2026 the Overseerr and Jellyseerr teams
merged into Seerr — one codebase with both
projects' features — and Overseerr's own repository was archived. All three speak the same
/api/v1, so an older instance keeps working: pick which one you run when you add it, and only
the label changes.
The top bar has its menus: Browse (Franchises, Collections, Spin-offs, Upcoming, Directors, Trophy case, In numbers); for administrators Playlists (one page with tabs) and Manage (Servers, Libraries, Instances, Users, Settings, Activity, Duplicates, Server parity); and one under your name (Preferences, Password, light/dark, grid density, Sign out), with search at the far right. The menu holding the page you're on is highlighted. On a phone it's a single ☰ button.
The home page leads with rows of posters: the collections you're closest to completing, films in franchises you own coming in the next 90 days, and titles just added to your library from sets you're collecting (counted from 0.45.0 on — nobody recorded when earlier ones arrived). The summary cards for each section sit below them.
Showcase look. Under your name, ✦ Showcase look switches you (and only you — it's saved to your account) from the everyday Classic look to a flashier one: franchise and collection banners go full-width with a slow zoom and parallax, the page takes on the colour of its artwork, headline numbers count up, and posters and cards tilt toward the pointer. The top bar stays pinned, frosted glass over the page; posters sharpen in as they load; a thin glow runs along the top while a button's request works; and on a collection, franchise or director page the films you don't have sit as dimmed, outlined gaps on the shelf. The home page opens on a big rotating spotlight of the collections you're nearly done with, which shrinks to a strip as you scroll, and its poster rows slide along with arrows. List cards show a completeness ring, and a light runs round any set one film from done; pausing on a collection or franchise card previews its backdrop and the films it's missing. Click a missing film's poster (or rest the pointer on it) and the card turns over to its plot, genres and score. The page's artwork lights the whole page, blurred, behind everything; your own posters drift in a wall behind the home page's heading; banners open like a film's title card; cards glide in as you scroll and the rest dim around the one you point at; a complete collection's poster and every trophy get a holographic foil; a running scan shows its progress in the browser tab; banners get darkened corners and their name in huge outlined type behind them; the release strip becomes a strip of film; headline numbers roll like an odometer; a slim bar keeps a detail page's name in view as you scroll; pointing at a collection card fans its films out; a new Trophy case badge unlocks with a flourish; a set that's mostly one genre has its banner's picture graded to suit (sepia for westerns, grey for crime, a flicker for horror); a collection or franchise page ends with its end credits rolling up — each title, its year and who directed it — to The End, or To be continued… while titles are missing; adding a film prints you a ticket stub; 📚 Shelf shows Collections or Franchises as box sets on a shelf; clicking an owned film's poster (or the page's own) opens it large, and the arrow keys or a swipe step through every poster in the set; a projector beam shines across the home spotlight; empty and finished pages get a little scene; a set's poster is black and white with colour risen up it as far as you own, and a detail page's poster stands as a 3D box set; coming-soon films count down their days on a split-flap board; a watched film's poster has its ticket punched; TV shows sit in old CRT screens; a trailer dims the house lights; a running scan plays on a projector; Activity's adds are a roll of ticket stubs; posters blur up from a tiny copy instead of popping in; a collection's, franchise's or director's banner shows the set as cinema seats, one lit for each film you own, and the page takes its art's colour for its links and buttons; and a hundred and twenty-eight franchises open with a nod to their films (listed below) (and there's a code for a retro VHS mode, if you know it); Ctrl+K (Cmd+K on a Mac) searches from anywhere; and in October horror sets glow pumpkin, in December the top bar frosts over. The release strip plays as it comes on screen (posters fly in in order, the ones you own light up, a ring fills to how much you have); and a poster you click grows into the page it opens (in browsers with view transitions: Chrome, Edge, Safari). Phones get the calmer half (no parallax, tilt, arrows, previews or ambient light, and a shorter spotlight that stays put), and your device's "reduce motion" setting turns the motion off. ✨ Effects in the menu under your name is your own dial: full, calm (every look kept, but nothing loops or flashes) or off (no motion at all, as reduce motion). ◻ Classic look switches back.
In both looks, a director's page has their photo softened behind the banner and their career as a strip in release order, marked by decade, and a long list sorted by release date gets a slim heading where each decade starts. A film with no poster gets a typeset card — its title and year on a colour of its own — instead of a grey box. Long lists (Collections, Franchises, Directors) have an A–Z rail down the side. Cards show how much of what you own you've watched, under the owned bar, and a detail page says how long the set runs (9h 40m across the 5 films you own · 3h 10m still to watch, from the running times your server reports). The home page opens with Up next — the next film you own and haven't watched in each set you've started — and In numbers charts the library: films by decade, how much is watched, the nearly complete sets, genres and the directors you own most. ▤ Density under your name switches every grid to compact cards, about twice as many on a screen.
Owned posters carry their best copy's resolution (4K, 1080p…, from your server's listing), and the film to watch next in a set is marked Next (or Start here). List cards show their set as a row of dots in release order — filled for owned, hollow for missing — so the gaps show at a glance. A collection page says which franchises it's part of, and a franchise page lists its collections. The home page has On this day (films you own released on today's date), the Trophy case has Almost on the shelf (sets a few titles short, and which), and ⤴ Share on a set's release strip makes a picture of it — posters in order, missing ones dimmed — drawn in your browser. Press ? for the keyboard shortcuts, and g then a letter to jump (g c: Collections).
When a scan finds you've completed a collection — every released film of it in your library — Showcase throws confetti with a "Collection complete!" message, once for each person, on their next visit to the home page or that collection. (Collections already complete when you first upgrade aren't news, and don't count.) While a scan runs, a film reel turns and the progress bar runs like film.
🎲 Surprise me on the home page (and at the top of Showcase's Ctrl+K box) picks a film you're missing at random — one rated 6.5 or more on TMDb by at least 50 people, from your collections and directors' lists, and not one you've dismissed — with its plot, where it's from, an Add button and Spin again. Showcase spins through posters like a slot machine before it lands.
▶ Trailers, in either look: a missing film's tile (collection, franchise and director pages), the Surprise me card, the back of a turned-over poster and the Showcase spotlight each have a play button, which opens the trailer TMDb lists in a pop-up. It plays in YouTube's privacy-enhanced player (youtube-nocookie.com); nothing from YouTube loads until someone presses play, and then YouTube sees your Franchisarr's address (the origin only — its player won't play without it).
Each franchise page has a Map of how the franchise fits together — its collections, its other films and its shows, with which show spun off which — in three shapes: Lanes (a timeline lane per series), Tree (the franchise, its series, their titles) and Constellation (a web you can drag about). Your pick is remembered; owned titles are filled in, missing ones hollow, and each leads to its collection page.
The Trophy case (Browse → Trophy case, in either look) shelves everything your library has finished — every collection, franchise and director's filmography with each released film in it — newest first, with milestone badges (first complete collection, 10, 25, 50…) and how far off the next one is. Showcase frames them in gold.
Franchise and collection pages open with the whole set in release order — a strip of posters, the ones you have in colour and the ones you don't dimmed, so the holes in the run show at a glance. Pick a dimmed one to add it; the lists below have everything else.
In the Showcase look, these franchises' collection and franchise pages open with a nod to their films — in this app's own words and drawing, with no logos, music or lines from the films. Each plays once per visit to a page; a click or any key skips it, ▶ Intro on the page plays it again, 🎬 Franchise intros in the menu under your name turns them off for you, and your device's "reduce motion" setting turns them off altogether. Completing one of these franchises also brings its own confetti. A small gold clapperboard on a card — in the Collections and Franchises lists (and on the shelf), the home page's rows and spotlight, the Trophy case, search and Ctrl+K — marks a set whose page has one; it isn't shown to anyone who has intros switched off.
Every other collection and franchise gets a shorter genre intro (about two and a half seconds), built from its own name, counts and poster: a 3-2-1 countdown leader for most, and for a set that's mostly one genre, flickering red for horror, hyperspace for sci-fi, bouncing colour for animation, a wanted poster for westerns, searchlights for war, swirling sparkles for fantasy, or rain and venetian blinds for crime. Only the franchises below carry the gold clapperboard on their cards.
| Franchise | Plays on pages named | What happens |
|---|---|---|
| Star Wars | Star Wars | "A short while ago, in a library not so far away…", then a crawl about your collection — how many films you have and the rest still at large — receding into the stars |
| The Matrix | Matrix | Falling green code |
| Harry Potter | Harry Potter, Wizarding World, Fantastic Beasts | Gold sparks thrown from the title, as from a wand (the page stays usable) |
| Marvel Cinematic Universe | Marvel Cinematic Universe, The Avengers Collection, Iron Man Collection, Thor Collection, Captain America Collection, Spider-Man (MCU)…, Guardians of the Galaxy Collection, Captain Marvel Collection and the other MCU solo series | Your own posters flick past like comic pages, faster and faster, then a red flash |
| James Bond | James Bond | Dots across a black screen, a gun barrel opening onto the page, a red wash, then the circle widens |
| Star Trek | Star Trek | Stars stretch into streaks, the jump to warp, a white flash |
| Jurassic Park | Jurassic Park, Jurassic World | A glass of water ripples with each distant thud, and the page shakes (the page stays usable) |
| Back to the Future | Back to the Future | A time-circuit display — latest film, today, first film — then twin fire trails |
| Mission: Impossible | Mission: Impossible | A burning fuse and a briefing about your missing films, which then self-destructs |
| Alien | Alien…, Prometheus…, AVP… | A motion tracker, one contact for each missing film, closing in |
| Batman | Batman, Dark Knight | A searchlight sweeps the clouds and settles into a bat signal |
| Jaws | Jaws | The page under water, a fin cutting slowly across, then the water drains away |
| Terminator | Terminator | A red targeting display frames the poster and lists your missing films as targets |
| Indiana Jones | Indiana Jones | An old map, a red route travelling through the films in release order |
| Middle-earth | Lord of the Rings, Hobbit, Middle-earth | A gold ring turning in the dark, glowing hotter, then flaring |
| Ghostbusters | Ghostbusters | Green slime runs down the screen in uneven drips, then slides away |
| Godzilla | Godzilla, MonsterVerse | Footsteps shake the page, dust falls, a vast shadow passes and a blue glow rises (the page stays usable) |
| Mad Max | Mad Max, Furiosa | A sandstorm tears across the screen, then blows itself out (the page stays usable) |
| Toy Story | Toy Story | A blue sky of fluffy clouds, which part to let the page through |
| Fast & Furious | Fast and the Furious, Fast & Furious, Hobbs & Shaw | A speedometer swings into the red, a blue flash, then the page tears past in streaks and tyre smoke |
| Rocky | Rocky…, Creed… | A bell, then a run up a long flight of steps at dawn — a step for each film — to arms raised at the top |
| Die Hard | Die Hard… | A tower block's windows light up floor by floor, then glass bursts out across the screen |
| Transformers | Transformers, Bumblebee… | The poster in mechanical panels, flung apart, that slide, turn and lock back together |
| Scream | Scream… | A phone rings in the dark — caller unknown — with a question about your missing films, then a slash cuts the dark in two |
| Paranormal Activity | Paranormal Activity | The page as night-vision footage with a running timestamp; it flickers and the frame jolts (the page stays usable) |
| Final Destination | Final Destination | A chain reaction of dominoes, one per film, until the last brings the curtain down |
| Predator | Predator | The page in heat colours, a shimmering outline crossing it, three red dots settling on the title (the page stays usable) |
| Dragon Ball Z | Dragon Ball | An aura builds round the title, crackling, the page shakes harder, then a blast of light (the page stays usable) |
| X-Men | X-Men, Wolverine…, The Wolverine… | A dome of light scans a crowd of points and locks on to one for each film you own, then flashes outward |
| Pirates of the Caribbean | Pirates of the Caribbean | A compass needle spins and settles, the sea rolls in, and the waves part to let the page through |
| Resident Evil | Resident Evil | A red laser grid sweeps down a dark corridor, then a containment report lists your missing films |
| Bourne | Bourne | A surveillance map: a dot hops from city to city, one per film, with readouts, until the signal is lost |
| Ice Age | Ice Age… | Frost creeps in from the edges and freezes the screen, then cracks and falls away (the page stays usable) |
| Twilight | Twilight Collection, The Twilight Saga | A misty blue-grey forest; a shaft of sunlight breaks through and the title sparkles |
| Shrek | Shrek, Puss in Boots | A storybook opens on your collection's tale; a page turns, then one is torn out |
| Halloween | Halloween… | A carved pumpkin flickers in the dark, its candle guttering, until it blows out |
| The Conjuring | Conjuring, Annabelle… | An instant photo slides in and develops into your poster — with a shadow in it that wasn't there before |
| The Exorcist | Exorcist | A foggy street at night, a lone figure under a streetlamp, the light flickering as the fog rolls in |
| The Purge | The Purge… | An emergency broadcast: alert bars, a notice about your missing films, a ticker and a red siren sweep |
| John Wick | John Wick | Neon rain on a dark street, and a gold coin spinning down to land on the title |
| Bad Boys | Bad Boys… | The title turns a slow full circle against a hot sunset and palm trees |
| Rambo | Rambo, First Blood… | Dense jungle fills the screen, rustling, then is slashed apart |
| Starship Troopers | Starship Troopers | An old newsreel: a service bulletin tallying your films, and a swarm massing on the horizon |
| Home Alone | Home Alone | A snowy house at night with its lights on, and a paint can on a rope swinging down across the screen |
| Kung Fu Panda | Kung Fu Panda | Ink brush strokes on rice paper paint the title, with peach blossom drifting |
| Jumanji | Jumanji | Two dice roll across a board — landing on the number still missing — then jungle vines cover the screen |
| Avatar | Avatar Collection | A dark forest lights up in blue and violet, ripple by ripple, with drifting seeds of light |
| The Hunger Games | Hunger Games | An arena countdown, a cannon for each missing film, and three lights rising across the sky |
| The Mummy | The Mummy… | Sand blows across a wall of carved symbols, gathers into a great face and crumbles away |
| Superman | Superman, Man of Steel | Clouds rush past as if climbing; a red-and-blue streak shoots up through them, and a flash |
| Sharknado | Sharknado | A tornado spins up, sharks whirling round in it, then tears off sideways |
| The Ring | The Ring… | Static, a stone well in a dark clearing, static again, and the set switches off to a line |
| 28 Days Later | 28 Days…, 28 Weeks…, 28 Years… | A red spread across an empty city map, a stage per film, as the days count up |
| Blair Witch | Blair Witch | Shaky torchlight in dark woods, twig figures hanging from the branches, and the camera drops |
| Deadpool | Deadpool | Comic captions that know they're in an intro and comment on your collection, then two slashes |
| Blade | Blade… (but not Blade Runner) | A red strobe in the dark, then a silver blade arcs across and the page appears in its wake |
| RoboCop | RoboCop | A robotic display boots, states three directives about your library, and scans the title |
| Kingsman | Kingsman | A black umbrella spins open to fill the screen, then snaps shut on the page (the page stays usable) |
| Men in Black | Men in Black | Dark glasses slide down, then a flash — and you never saw how many films are missing |
| TRON | TRON | Light trails race across a neon grid, turning square corners, then the grid flies off |
| The Godfather | Godfather | A dim, sepia room with smoke under one lamp; the title fades up in an elegant hand and dissolves |
| Planet of the Apes | Planet of the Apes | A red sunset over overgrown ruins, and an ape's silhouette with a spear rising on the skyline |
| How to Train Your Dragon | How to Train Your Dragon | A dragon silhouette swoops past through dusk clouds, wings beating, and banks away |
| Cars | Cars… | Racing stripes zoom past, then a checkered flag waves and sweeps the page in |
| Night at the Museum | Night at the Museum | A dark hall, the lights flicker on, and a dinosaur skeleton turns its head to look at you |
| The Chronicles of Narnia | Narnia | Wardrobe doors open on snowy woods, a lamp-post glowing in the snow |
| Insidious | Insidious | Pitch dark; a red door glows at the far end, creaks open, and something breathes out of it |
| The Shining | The Shining…, Doctor Sleep… | A long hotel corridor with a bold patterned carpet rushes past, down to a door at the end |
| The Thing | The Thing… | An Antarctic blizzard at night, a lone outpost light blinking, the snow thickening to white-out |
| Underworld | Underworld… | Blue moonlit rain over gothic rooftops, the full moon behind cloud, lightning |
| Top Gun | Top Gun | Jets streak across a sunset trailing contrails, a flare of sun as they bank away |
| Ocean's | Ocean's… | A vault dial spins to a combination — what you have, how many there are, how many are missing — and the door swings open |
| The Equalizer | Equalizer | A stopwatch races while the room blurs past, then stops with a click |
| Lethal Weapon | Lethal Weapon | Red and blue lights sweep a dark street strung with Christmas lights |
| 2001: A Space Odyssey | Space Odyssey, 2001… | A black monolith, and a sunrise climbing over a planet's edge into alignment above it |
| Venom | Venom… | Glossy black tendrils creep in from the edges, writhing, then snap back (the page stays usable) |
| Wonder Woman | Wonder Woman | A golden lasso spins and widens into a ring of light that sweeps the screen |
| Spider-Man | Spider-Man…, The Amazing Spider-Man…, Spider-Verse (the MCU's Spider-Man plays the MCU intro) | A line of web shoots in from a corner, a web spreads from the middle, and the title is caught in it |
| The Lion King | Lion King | A savanna sunrise: a huge orange sun, acacia trees, and herds crossing the horizon |
| Wreck-It Ralph | Wreck-It Ralph | The poster breaks into chunky 8-bit pixels that crumble away, then fly back and rebuild |
| The Incredibles | Incredibles | Retro sixties title cards: bold colour blocks slide in and out, then the title |
| Despicable Me | Despicable Me, Minions… | A shrink ray zaps the page down to nothing, then it pops back (the page stays usable) |
| Beverly Hills Cop | Beverly Hills Cop | A sunny palm-lined boulevard rushing past, police lights flashing behind |
| Kill Bill | Kill Bill | A stark yellow screen with the title in black; a katana stroke slices it in two and the halves slide apart |
| Taken | Taken… | A city map zooming in, a pin dropping for each missing film, labelled |
| The Expendables | Expendables | A wall of fire, and a row of silhouettes walking out of it toward you, one per film you own |
| Austin Powers | Austin Powers | A psychedelic sixties swirl, bands of colour and flowers spinning out from the middle |
| The Mask | The Mask Collection, Son of the Mask (not The Mask of Zorro) | A green whirlwind spins across the screen and stops dead with a cartoon pop (the page stays usable) |
| Zombieland | Zombieland | Survival rules stamped on screen one at a time, in your library's own terms |
| Hotel Transylvania | Hotel Transylvania | Bats swirling round a spooky castle hotel at night, its windows lighting up one by one |
| Tomb Raider | Tomb Raider | A torch-lit tomb floor whose stone tiles crack and fall away, leaving the page beneath |
| Pacific Rim | Pacific Rim | Rain over a dark sea; a giant robot's silhouette rises, and its chest lights up |
| National Treasure | National Treasure | An old map warms, and hidden writing appears on it: your missing films, as clues |
| Sherlock Holmes | Sherlock Holmes | A magnifying glass sweeps a foggy gaslit street, noting clues about your collection |
| Knives Out | Knives Out, Glass Onion, Wake Up Dead Man | A sunburst ring of knives turns slowly; one is drawn out and the ring falls apart |
| Teenage Mutant Ninja Turtles | Ninja Turtles | Sewer pipes, and four coloured masks flashing past one after another |
| Sonic the Hedgehog | Sonic the Hedgehog | A blue streak loops around the screen collecting gold rings, then zooms off |
| It | It Collection, It Chapter… | Rain on a dark street, and a single red balloon floating up out of a storm drain |
| Evil Dead | Evil Dead | The camera rushes low and fast through dark woods to a lone cabin, whose door bursts open |
| Beetlejuice | Beetlejuice | Black-and-white stripes swirl into a spiral, a little model town spinning in the middle |
| Hocus Pocus | Hocus Pocus | A black-flame candle lights, green fog rolls, and three witches on brooms cross a full moon |
| Dune | Dune… | Golden dunes shimmering in the heat, and a vast ripple travelling under the sand toward you |
| Blade Runner | Blade Runner | A neon city in the rain at night, flying cars drifting past glowing towers |
| Hellboy | Hellboy | Red flames lick up the edges, then a great stone fist punches in and the screen cracks |
| Gladiator | Gladiator… | A hand brushing through golden wheat at sunset, then arena gates grinding open |
| Frozen | Frozen… | Ice crystals spread from the centre into a great snowflake, then shatter into sparkles |
| Finding Nemo | Finding Nemo, Finding Dory | Underwater: rays of light, bubbles, coral, and a small orange fish darting across |
| Monsters, Inc. | Monsters, Inc., Monsters University | Doors whizz past on a factory rail; one stops, opens, and light spills out |
| Inside Out | Inside Out | Glowing memory orbs in five colours roll in and line up, one per film (dimmer for the ones you're missing) |
| The Hangover | The Hangover… | Morning-after camera flashes: blurry snapshots, ending on your collection's poster |
| Scooby-Doo | Scooby-Doo | A groovy flower-painted van drives across, then a sheet ghost is unmasked |
| Joker | Joker… | A playing card spins in purple and green light and lands face up on the joker |
| A Nightmare on Elm Street | Elm Street | A hot red boiler room hissing steam, then four claw marks slash across the screen |
| Saw | Saw… | A flickering bulb over grimy tiles, a jigsaw-piece timer counting down, then the light dies |
| Psycho | Psycho… | In black and white, a shower curtain is torn aside, its rings snapping, and the water spirals down the drain |
| World War Z | World War Z | A swarm of figures pours up and over a high wall like a wave |
| 300 | 300… | A sepia sky over a wall of shields, then a volley of arrows that blots out the sun |
| The Karate Kid | Karate Kid, Cobra Kai | A silhouette balancing in a crane stance on a post by the sea at sunset |
| The Meg | The Meg…, Meg… | A tiny boat on calm water, and a colossal shark's shadow gliding underneath |
| Mortal Kombat | Mortal Kombat | Fire from one side, ice from the other; they meet in the middle in a flash |
| Airplane! | Airplane… | A propeller plane bobbing through clouds as a "fasten seat belts" sign flickers |
| Ace Ventura | Ace Ventura | A parade of jungle animal silhouettes trotting across a tropical sunset |
| Anchorman | Anchorman | A seventies TV news card — "Breaking news" — with your collection as the headline |
| Spaceballs | Spaceballs | A ridiculously long spaceship takes forever to scroll past overhead |
| The NeverEnding Story | NeverEnding Story | An old book glows and its pages fly out, swirling into a vortex |
| The Polar Express | Polar Express | A steam train's headlight cutting through falling snow, steam billowing |
| Moana | Moana… | Ocean waves rise into a towering wall of sparkling water, which then parts |
| Paddington | Paddington | A little suitcase and hat, and a luggage label tied on with a note about your collection |
The magnifying glass at the right of the top bar (or pressing /) opens a search over everything Franchisarr knows: the collections and franchises you own part of, directors with a page, and every film and show it has come across — in your library, in a collection, a franchise, a director's filmography or a spin-off list. Results appear as you type and are grouped by kind. Each film or show says whether you have it (and on which server), whether Radarr or Sonarr already has it, or whether it's missing or not out yet, and links to the pages it belongs to; missing ones have Add and Not interested. Case, accents and punctuation don't matter: spiderman finds Spider-Man and amelie finds Amélie. It searches what's already here, not all of TMDb.
Franchise, collection and director pages have a Make a playlist button in their banner (administrators only). It builds a playlist of everything you own on that page, on each of your Plex, Jellyfin and Emby servers that holds some of it, in the order it was released: films by release date, and for a franchise that spans film and TV, every episode placed by its air date — so Agents of S.H.I.E.L.D. falls between the Marvel films as it was broadcast. Specials (season 0) are left out. With more than one server the button opens a menu — On every server, or On Plex, On Jellyfin and so on for just one. Once Franchisarr is keeping one, the banner says where ("✓ Playlist kept on Plex, Jellyfin") and the button reads Refresh playlist.
- It's called "name (Franchisarr)" and gets its own square poster: the franchise or collection backdrop across the top, and the name, "In release order" and what's in it ("13 films · 3 shows · 279 episodes") on a dark panel below (a director gets their film posters instead). Playlists with any other name are never touched.
- It's kept current. After every scan (and at every sync), titles you've added since go in where they belong and ones you've removed come out. The playlist is edited in place, so it keeps its poster and its spot in your apps. Delete it on any server and Franchisarr deletes it on the others too and stops keeping it. A server that's off or can't be reached is never taken for a deletion.
- Playlists belong to one account. On Plex that's the account of the token Franchisarr uses — normally yours as the server owner. On Jellyfin and Emby it's the server's watched as user (Servers page), which is the first administrator unless you've set one.
- Chronological, too. A collection or franchise page has two ticks above the button — Release order and Chronological — so it makes either playlist or both. The chronological one, "name — Chronological (Franchisarr)", follows the story: Rogue One before A New Hope, Prometheus before Alien, a show's episodes together where the show falls. Built-in story orders cover the big franchises where the two differ (Star Wars, the MCU, Star Trek, X-Men, Alien, Predator, Planet of the Apes, the DC Extended Universe, Fast & Furious, the Wizarding World, Middle-earth and twenty-five more); any collection or franchise can be given its own, or the built-in one changed, in Story order… under its banner — drag the titles or use ↑ ↓. A title the order doesn't place goes at the end, in release order. Directors are release order only.
One page for administrators, with four tabs. At the top: how many playlists are syncing and being kept, when the last run was and anything that couldn't be copied, Sync now, and when syncs run — always after every scan and on Sync now, and optionally every hour, 6 hours, 12 hours, daily, or on a cron schedule of your own.
- Your playlists — keep your own playlists in step between servers, both ways (below).
- Franchisarr's — every playlist Franchisarr keeps, in collapsible Franchises / Collections / Directors groups with a thumbnail and a chip per server for what it holds there, and a Remove button (deletes it everywhere). Put them on chooses the servers they go on; unticking one deletes them there. Add many at once makes one for every franchise, collection and/or director you tick, on one server or all, in the background with progress and a Stop button; a set with fewer than two titles on a server is skipped there.
- Clean up — on one server or every server: Delete Franchisarr's playlists removes only playlists named "… (Franchisarr)" (and stops them going to that server); Delete all playlists removes every playlist in the account Franchisarr uses (on Plex the token's owner; on Jellyfin and Emby the watched as user), including ones made by hand, and needs DELETE typed. Jellyfin and Emby don't say who owns a playlist, so one shared with that account may be listed too. Both list exactly what would go before anything is deleted.
- History — the last 30 runs.
Your playlists is a checklist of the playlists on each server, one collapsible section per server (closed to start: they can be long). A text filter and All / Syncing / Not syncing / Problems chips narrow it, opening the sections with matches; each synced playlist shows a chip per server (✓ Attic 18/20, ⚠ blocked) that opens to say more. Tick the ones to keep in step across your servers; once anything has changed, a bar at the bottom of the screen counts the changes and offers Save and sync or Undo. At the top, Copy to sets which servers get copies — every other one by default, which also takes in servers you add later; any playlist can have its own with change. Tick new playlists automatically syncs playlists made later too; untick any one to leave it out. Save and sync applies it straight away.
It works both ways. At each sync, a title added to the playlist on any server is added on the others (after the title it followed there), and one removed from it on any server comes off the others. A rename on any server renames the rest. The order follows the original.
- Titles are matched by TMDb id — a film by its own, an episode by its show plus season and episode number. One a server doesn't have is left out there, and the page lists what's missing and why — with Add for a film Radarr doesn't have yet, or a show Sonarr doesn't. A title a server can't hold is never read as removed there.
- A copy starts with the same name and, if the playlist has its own poster, the same poster.
- Deleting the original deletes its copies. Deleting a copy on its server stops copying there (that server is unticked for it); unticking a server deletes the copy there. Unticking a playlist stops syncing it and leaves its copies as ordinary playlists.
- A playlist of the same name that sync didn't make is never touched: that copy shows as blocked, with Link them to treat it as the copy — the two lists are merged, so titles from either end up in both.
- A Plex smart playlist follows its own rules, so it's copied as it stands, one way.
- It uses the same accounts as everything else here (the Plex token's owner, the Jellyfin/Emby watched as user). Music and photo playlists aren't synced, and Franchisarr's own are kept on their own tab. A sync that fails sends a notification, if you've set one up.
▦ Calendar on the Upcoming page lays the announced films out month by month, each poster on its release day (☰ List switches back; the page remembers which you chose). The page is also an iCalendar feed, so announced films in franchises you own appear in your calendar app — one all-day event per film, with the collection and how much of it you have:
https://franchisarr.example.com/api/lists/upcoming.ics?api_key=YOUR_KEY
Apple Calendar: File → New Calendar Subscription. Google Calendar: Other calendars → From URL. Same key as the import lists (Settings → Import lists), and the URL is shown there. It refreshes daily; films with no date yet appear once TMDb gives them one.
After a scan that finds something new — scheduled or started by hand, never every run, and
never the very first scan, whose findings are the state of your library rather than news —
Franchisarr sends one message. Settings → Notifications takes a Discord or Slack webhook, a generic JSON webhook for
your own automation, or Apprise URLs, one per line (tgram://…, pover://…, ntfy://…,
mailto://…; the Apprise wiki lists every service),
delivered from inside the app. If you already run
apprise-api, point it at that instead and keep the
destinations there. The URL is treated as a credential: redacted in logs and in the redacted
config export.
Rather have one message a week? Choose A weekly digest under the same section, with its day and hour: scans then save up what they find, and the digest sends a week of it at once — new gaps, spin-offs, release dates announced or moved — and holds on to it if delivery fails.
On a collection, franchise or director page an administrator can Add all N missing at once: a confirm lists every film and where it's going (the Radarr instance, profile and folder, or a Seerr), then adds them one by one and says how each went. Never automatic, and never the titles a taste filter folded away. Hide from my lists on a collection or franchise folds it out of your lists and home page only — into a section at the foot of the list, never gone — for sets you'll never finish and don't want to see. Under Manage, Duplicates lists films in the library more than once on a server (two libraries, or several versions of one film), and Server parity — for installs with more than one media server — lists the films each server has that another doesn't, a paused one included as of its last scan.
/api/lists/stats.json?api_key=… returns the headline numbers as one flat document — collections
with gaps, missing films, spin-offs, upcoming films, incomplete franchises, directors, library
size, last scan — cached for a minute. For Homepage:
- Franchisarr:
icon: https://raw.githubusercontent.com/prophetizer/franchisarr/master/docs/brand/icon-512.png
href: https://franchisarr.example.com
widget:
type: customapi
url: https://franchisarr.example.com/api/lists/stats.json
headers:
X-Api-Key: your-key
refreshInterval: 300000
mappings:
- field: missing_films
label: Missing films
format: number
- field: collections_with_gaps
label: Collections
format: number
- field: missing_spinoffs
label: Spin-offs
format: number
- field: upcoming_films
label: Upcoming
format: numberThe key is the one from Settings → Import lists; the header keeps it out of your dashboard's
URL list, but ?api_key= works too for widgets that can't send headers.
Sign in with your media server account. For Plex that is the usual OAuth button, and Franchisarr never sees your Plex password. By default only the account that owns your Plex server gets in: a Plex account that doesn't own it is refused, and so is anyone it's merely shared with (see below to let them in). For Jellyfin and Emby it is a username and password, checked against the server itself. Who administers Franchisarr follows from the server: with Plex it's the server's owner, with Jellyfin and Emby it's anyone who is an administrator there — checked again every time they sign in, so handing the server over, or demoting someone on Jellyfin, takes their admin rights here with it. The sign-in page has a Sign in with dropdown listing each way in this install offers (Emby, Jellyfin, Plex, and the local account if one is set up), shows only the one you pick, and remembers it in that browser.
By default only administrators can sign in. Being able to reach your Plex server is a much wider group than the people who run your house, so friends and family you share it with are refused. If you want them in, turn on Settings → Who can sign in. They can then browse the lists and hide titles for themselves, but they can't add anything to Radarr, Sonarr or Seerr, start scans, or change settings, and they don't see those controls. Turning it off again signs them out and stops their API keys. Settings → Users lists everyone who has signed in, and can sign someone out everywhere, revoke their API key or remove them.
The local admin account from ADMIN_USERNAME/ADMIN_PASSWORD is the fallback for when no server
is configured yet, or plex.tv is unreachable. It's created on first boot only, so changing those
variables later has no effect — if you forget the password:
docker exec -it franchisarr python scripts/reset_admin_password.py # lists accounts
docker exec -it franchisarr python scripts/reset_admin_password.py admin # prompts for a new oneIf no sign-in button is offered, Franchisarr couldn't reach your server at startup — with Plex it has to know which server it belongs to before it can check that an account is allowed in. Press Test on the server under Servers, or check that server's address and key and restart.
On first boot every filled-in pair in .env becomes a server; after that, add and change them
under Servers in the app (name, address, key; a watched as username for Jellyfin/Emby, since an API key belongs to
nobody). Their libraries are chosen together on the Libraries page and scanned in one pass. A
film on two servers is owned once; its tile on a collection page says which servers hold it. Watched films get a
tick, and the Collections page can be filtered to franchises you've actually started.
Each server on the Servers page has its own Scan button (just that server's libraries) and a Turn off / Turn on switch. A server that's off isn't scanned, isn't a playlist target, and nothing on it counts as owned; what it holds stays in the database, so turning it back on needs no rescan. Use only this turns every other server off at once, with a banner on every page to turn them back on: the quick way to see what one server has on its own.
The CLI talks to Franchisarr's own API, so it works through docker exec or from anywhere that
can reach the app.
export FRANCHISARR_URL=http://localhost:8000
export FRANCHISARR_API_KEY=... # an admin's key: Settings, or `cli.py api-key`
python cli.py scan
python cli.py gaps
python cli.py add 176 --instance 1scan walks your libraries, films and TV together; gaps and spinoffs list what's missing;
review shows matches that need confirming; add, add-show and add-collection send things to
Radarr/Sonarr; instances and activity inspect the rest. Scanning and adding need an
administrator's key, like the buttons they stand in for.
Nord (dark) by default, with a light toggle to Nord's light half. theme.park themes are set by environment variable, using theme.park's own names — so if your stack already sets these, Franchisarr picks the theme up with no per-app configuration:
environment:
TP_THEME: nord
TP_DOMAIN: theme-park.dev # or your own self-hosted copy
TP_SCHEME: https
TP_COMMUNITY_THEME: "false"THEME_CSS_URL overrides those with a literal stylesheet URL.
If you theme centrally by injecting a stylesheet at the proxy — nginx sub_filter, a Traefik
plugin, theme.park's Docker mod — that works with nothing set here at all. Franchisarr always
loads a small adapter mapping theme.park's custom properties onto the ones it paints with, so an
injected theme-options stylesheet takes effect on its own. The whole page follows the theme,
header icon included — verified against all eleven official theme options
(screenshots).
Franchisarr's base stylesheet — the one a proxy or the theme.park mod injects when you point
it at app=franchisarr — was
merged into theme.park on 2026-09-22.
It is on their develop branch, so develop.theme-park.dev serves it today and
theme-park.dev will once they cut a release. If you host your own copy,
contrib/theme-park/franchisarr-base.css is the same file, ready to drop in as
css/base/franchisarr/franchisarr-base.css (see
contrib/theme-park/README.md).
Leave it all unset and no stylesheet is fetched from anywhere but your own server.
Honest about what has run against the real thing and what has only run against the test suite:
| Piece | Tested against |
|---|---|
| Plex | The developer's own library — ~3,400 films, ~660 shows — every day |
| Jellyfin 10.11, Emby 4.9 | Real servers during development, library scans and sign-in both; not in daily use |
| Jellyfin 12.1, Emby 4.10 | Connection, library listing and playlists (build, poster, editing in place, sync) against real servers (September 2026) |
| Seerr 3.4.1 | End to end on a real instance: connection, request cache, and a real request through to Radarr (September 2026). That first live test found three bugs, fixed in 0.23.1 |
| Radarr 6.3, Sonarr 4.0 | Real instances, one of each, every day |
| Several Radarr or Sonarr instances | The test suite only — the developer runs one of each |
| Overseerr, Jellyseerr | The test suite only; they speak Seerr's API, which is tested for real |
| Unraid template | Not yet run on Unraid — coming after more testing |
| Large libraries | A synthetic 20,000-film, 2,000-show library (scripts/loadtest.py) |
| Sign-in for people you share with | The test suite only: refused by default, the Settings switch, and what they can and can't do once let in. No real shared account has signed in on the developer's install |
If your setup is in one of the lower rows and something doesn't work, that's the most useful bug report there is.
Everything Franchisarr contacts, from the server:
| Service | When | Why |
|---|---|---|
TMDb (api.themoviedb.org) |
During scans | Collections, films, shows, directors — needs your free key |
Wikidata (query.wikidata.org) |
During scans | Spin-offs, continuations and franchises. No account; requests carry a User-Agent naming this project, as Wikidata asks |
| plex.tv | Only when someone signs in with Plex | The sign-in PIN flow, and checking the account can reach your server |
| fanart.tv | Only if you set a fanart.tv key | Franchise logos |
TMDb's image CDN (image.tmdb.org) |
Only when you make a playlist | The artwork for the playlist's poster, which Franchisarr composes and uploads to your media server. Not with SHOW_ARTWORK=false |
GitHub (api.github.com) |
When Settings is opened | The update banner. Sends nothing about you or your library. Off under Settings → Update check, or with UPDATE_CHECK=false |
Plus whatever you point it at yourself: your media servers, Radarr, Sonarr, Seerr, a webhook or Apprise, a theme.park host. In the browser, posters load from TMDb's image CDN and logos from fanart.tv's.
No telemetry, no analytics, no accounts with anyone but the services above.
Settings has a config download. The full one contains your media server credentials and every API key in plain text — treat it like a password. There's a redacted download alongside it with those blanked out; that's the one to paste into a forum thread when asking for help.
Importing a backup restores settings, instances, spin-off mappings and your hidden titles. Media servers in it arrive switched off: a server decides who can sign in, so check each one on the Servers page and switch it on. Anything in the file that isn't a known setting or field is skipped.
docker compose pull franchisarr && docker compose up -d franchisarrThe database upgrades itself on start, and your settings, instances and dismissals are kept. The Settings page says when a new version is out (unless you've turned the update check off). Before a jump, skim the changelog: anything that changes how an existing install behaves has an Upgrading note — 0.25.0, for example, signs out everyone who isn't an administrator until you choose to let them in.
:latest and the version tags are releases. There is also a :develop image, built from every
change before it's released — it's what the developer runs, and it can be broken on any given day;
stay on :latest unless you want to try things early.
Settings also has Download diagnostics: version, library and cache counts, the titles that didn't match or need review, and the last scan's result, with every credential blanked. Attach it to a bug report — it answers most of what would otherwise be the first round of questions. Security issues go through private reporting, not a public issue.
Franchisarr can only work with an item if it can resolve it to a TMDb ID. Settings → Download diagnostics lists what didn't match on any server, which is the quickest way to see the shape of the problem. For Plex specifically there is also a standalone audit:
export PLEX_URL=http://your-plex-host:32400
export PLEX_TOKEN=your-plex-token
python scripts/plex_guid_audit.pyIt's read-only, and Plex-only — Jellyfin and Emby report their provider IDs directly, so there is nothing equivalent to audit. For each library it reports how many items carry a TMDb ID, which GUID formats are in use, and a sample of what didn't resolve. Libraries of home videos, concert rips or test clips will legitimately show 0% — untick those in Franchisarr rather than trying to match them.
If it ends with an UNRECOGNISED AGENTS section, please report it: your library uses a GUID format
Franchisarr doesn't parse yet, and that section says exactly what's needed.
python -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
pytest
DB_PATH=./franchisarr.db ADMIN_USERNAME=admin ADMIN_PASSWORD=change-me uvicorn app.main:app --reloadTests never touch the network — Plex, Jellyfin, Emby, TMDb, Wikidata, fanart.tv, Radarr, Sonarr and Seerr are all mocked. See docs/DEVELOPMENT.md for
the conventions this codebase holds itself to, and docs/DESIGN.md for the design and the
28 documented technical challenges behind it.
See SECURITY.md for how to report vulnerabilities.








