Automated rating overlays and collection management for Plex - Simple, fast, and powerful.
Kometizarr automatically adds gorgeous multi-source rating badges to your Plex movie and TV show posters. No more messy YAML configs, no database risks, just clean Python that works.
- 4 independent rating badges — TMDB, IMDb, RT Critic, RT Audience
- Independent positioning — Place each badge separately anywhere on the poster
- Visual alignment guides — Live grid overlay for precise badge placement
- 11 font options — DejaVu Sans/Serif/Mono in Bold, Regular, and Italic variants
- Per-badge customization — Font, color, opacity, size, and logo scale per badge
- Live preview — Render 3 real posters from your library before committing
- Backward compatible — Legacy unified badge still supported
- Dynamic RT logos: Fresh tomato/rotten splat for critic scores, fresh/spilled popcorn for audience scores
- Smart sizing: Logos scale proportionally, popcorn icons enlarged for visibility
- Perfect alignment: All ratings and logos line up beautifully
- 50% opacity background: Semi-transparent black rounded rectangle
- Color-coded text: Gold ratings, white symbols (/10, %)
- Drop shadows: Crisp text on any poster background
- Two independent cron schedules — Normal run (new items only) + Force run (refresh all ratings)
- Human-readable scheduling — Daily, Weekly, Every hour with a time picker — no cron syntax needed
- Plex Webhook — Automatically process the exact item added, the moment it's added
- Webhook queue — Bulk imports (10 items at once) handled cleanly, no dropped events
- Multi-library selection — Checkboxes for cron and webhook — pick any combination of libraries
- Settings tab — All automation configured from the Web UI, persisted across restarts
- Multi-library processing — Select any combination of libraries and process them in one click
- Real-time progress — WebSocket updates with live success/failure/skipped counts
- Library stats — Total items and processed count per library
- Stop button — Graceful abort mid-run
- Decade collections: Automatically organize by era
- Keyword collections: DC Universe, Zombies, Time Travel, etc.
- Studio collections: Marvel, Disney, Warner Bros
- Custom collections: Define your own criteria
- Dry-run mode: Preview before applying
- Safe operations: No database modifications, uses official Plex API
- Atomic operations: Each poster processed independently
- Automatic backups: Original posters saved before modification
- Easy restoration: One-click restore from the Web UI or CLI
- Rate limited: Respects API limits (TMDB, MDBList)
- Resume support: Skip already-processed items
Library selection, stats, badge positioning with drag-and-drop, and processing options — all in one view.
Real-time progress with WebSocket updates — success, failure, skipped, and remaining counts.
Two independent cron schedules plus Plex webhook — fully set-and-forget automation.
Create decade, keyword, and studio collections with presets or custom keywords.
Each rating source (TMDB, IMDb, RT Critic, RT Audience) positioned independently with custom styling, dynamic RT logos, and per-badge font/color/size options.
📦 Pre-built Docker Images Available:
- Docker Hub:
p2chill/kometizarr-backend:latest&p2chill/kometizarr-frontend:latest - GitHub Container Registry:
ghcr.io/p2chill/kometizarr-backend:latest&ghcr.io/p2chill/kometizarr-frontend:latest
No build required — just pull and run! ⚡
The easiest way to use Kometizarr is with the Web UI — a beautiful dashboard with live progress tracking and full automation!
Download docker-compose.example.yml, fill in your values, and rename it to docker-compose.yml. Or create it manually:
services:
backend:
image: ghcr.io/p2chill/kometizarr-backend:latest
container_name: kometizarr-backend
ports:
- "8000:8000"
volumes:
- ./data/backups:/backups # Poster backups (PERSISTENT)
- ./data/appdata:/app/kometizarr/data # Settings (cron, webhook config)
environment:
- PLEX_URL=http://YOUR_PLEX_IP:32400
- PLEX_TOKEN=YOUR_PLEX_TOKEN
- TMDB_API_KEY=YOUR_TMDB_KEY
- OMDB_API_KEY=YOUR_OMDB_KEY # Optional
- MDBLIST_API_KEY=YOUR_MDBLIST_KEY
restart: unless-stopped
networks:
- kometizarr
frontend:
image: ghcr.io/p2chill/kometizarr-frontend:latest
container_name: kometizarr-frontend
ports:
- "3001:80"
depends_on:
- backend
restart: unless-stopped
networks:
- kometizarr
networks:
kometizarr:
driver: bridgeThen run:
docker compose up -dOpen http://localhost:3001 — done in 5 seconds! 🎉
Alternative registries:
- Docker Hub: Replace
ghcr.io/p2chill/withp2chill/ - Version pinning: Replace
:latestwith:v1.2.1for stable releases
git clone https://github.com/P2Chill/kometizarr.git
cd kometizarr
cp .env.example .env
# Edit .env with your Plex credentials and API keys
docker compose up -d📄 View docker-compose.yml
services:
backend:
build: ./web/backend
container_name: kometizarr-backend
ports:
- "8000:8000"
volumes:
- ./:/app/kometizarr # Mount entire project
- ./web/backend:/app/backend # Mount backend source for hot-reload (no rebuild needed)
- ./data/backups:/backups # Poster backups (PERSISTENT - survives reboots)
environment:
- PLEX_URL=${PLEX_URL:-http://192.168.1.20:32400}
- PLEX_TOKEN=${PLEX_TOKEN}
- TMDB_API_KEY=${TMDB_API_KEY}
- OMDB_API_KEY=${OMDB_API_KEY}
- MDBLIST_API_KEY=${MDBLIST_API_KEY}
restart: unless-stopped
networks:
- kometizarr
frontend:
build: ./web/frontend
container_name: kometizarr-frontend
ports:
- "3001:80"
depends_on:
- backend
restart: unless-stopped
networks:
- kometizarr
networks:
kometizarr:
driver: bridgeThen open http://localhost:3001 in your browser! 🎉
Features:
- 📊 Visual dashboard with library stats and multi-library processing
- ⚡ Real-time progress with WebSocket updates (auto-reconnect on disconnection)
- 🎯 One-click processing with live progress tracking
- 📈 Live success/failure/skipped counts
- 🎨 Rating source filtering (choose TMDB, IMDb, RT Critic, RT Audience)
- 🔄 Browser refresh resilience (resumes monitoring active operations)
- ⏱️ 10-second countdown on completion with skip option
- 🛑 Cancel/stop button to abort processing mid-run
- ⚙️ Settings tab — cron scheduling, webhook, library maintenance
After starting the stack, open the Settings tab in the Web UI:
- Scheduled Processing — Enable either or both cron jobs, pick Daily/Weekly/Hourly and a time, select which libraries to include (none = all). Save.
- Plex Webhook — Copy the webhook URL into Plex → Settings → Webhooks. Enable and optionally scope to specific libraries.
That's it — Kometizarr will keep your ratings fresh automatically.
For advanced users or automation:
Prerequisites:
- Python 3.8+
- Plex Media Server
- TMDB API key (free) — https://www.themoviedb.org/settings/api
- MDBList API key (free) — https://mdblist.com/
- Optional: OMDb API key for IMDb ratings — http://www.omdbapi.com/
Installation:
git clone https://github.com/P2Chill/kometizarr.git
cd kometizarr
pip install -r requirements.txt- Copy example config:
cp config.example.json config.json- Edit
config.jsonwith your details:
{
"plex": {
"url": "http://YOUR_PLEX_IP:32400",
"token": "YOUR_PLEX_TOKEN",
"library": "Movies"
},
"apis": {
"tmdb": {
"api_key": "YOUR_TMDB_KEY"
},
"omdb": {
"api_key": "YOUR_OMDB_KEY",
"enabled": true
},
"mdblist": {
"api_key": "YOUR_MDBLIST_KEY"
}
},
"rating_overlay": {
"enabled": true,
"badge": {
"position": "northwest",
"style": "default"
}
}
}How to get your Plex token: https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/
Process entire movie library:
from src.rating_overlay.plex_poster_manager import PlexPosterManager
import json
with open('config.json') as f:
config = json.load(f)
manager = PlexPosterManager(
plex_url=config['plex']['url'],
plex_token=config['plex']['token'],
library_name='Movies',
tmdb_api_key=config['apis']['tmdb']['api_key'],
omdb_api_key=config['apis']['omdb']['api_key'],
mdblist_api_key=config['apis']['mdblist']['api_key'],
backup_dir='./data/kometizarr_backups'
)
# Process all movies (skips already processed)
manager.process_library(position='northwest', force=False)Process single movie:
movie = plex.library.section('Movies').get('The Dark Knight')
manager.process_movie(movie, position='northwest')Restore original posters:
# Restore single movie
manager.restore_movie('The Dark Knight')
# Restore entire library
manager.restore_library()TV Shows:
Same API, just use library_name='TV Shows' — works identically!
Tested on 2,363 movie library:
- Processing speed: ~0.5–4 movies/second depending on your CPU
- Total time: ~35–55 minutes for full library
- API limits: Respects TMDB (40 req/10s) and MDBList limits
- Memory usage: Minimal (processes one at a time)
Rate limiting:
- 0.3s delay between movies (default)
- Adjustable in
process_library(rate_limit=0.3)
Kometizarr is designed to be a lightweight, focused alternative for rating overlays:
- Simple Configuration: Single JSON config file, no complex YAML hierarchy
- Fast Processing: Direct API calls with efficient rate limiting
- Safe Operations: Official Plex API, automatic backups, atomic operations
- Flexible Workflows: Easy restoration, dry-run mode, skip processed items
- Beautiful Design: Multi-source ratings (TMDB, IMDb, RT), dynamic RT logos that change based on score
- Modern Stack: Clean Python code with optional Web UI (React + FastAPI)
- Plex-First Ratings: Extracts ratings from Plex metadata before hitting external APIs (97%+ success rate)
- True Automation: Cron scheduling + Plex webhook — fully set-and-forget
kometizarr/
├── src/
│ ├── rating_overlay/
│ │ ├── multi_rating_badge.py # Badge generation with dynamic logos
│ │ ├── rating_fetcher.py # TMDB, OMDb, MDBList API calls
│ │ ├── plex_poster_manager.py # Orchestration and Plex integration
│ │ ├── backup_manager.py # Original poster backups
│ │ └── overlay_composer.py # Poster compositing
│ ├── collection_manager/ # Smart collection management
│ └── utils/
│ └── logger.py # Clean progress tracking
├── web/
│ ├── backend/ # FastAPI backend with WebSocket
│ │ ├── main.py # API endpoints, cron scheduler, webhook
│ │ ├── Dockerfile
│ │ └── requirements.txt
│ ├── frontend/ # React frontend
│ │ ├── src/
│ │ │ ├── components/ # Dashboard, Settings, ProcessingProgress
│ │ │ ├── App.jsx
│ │ │ └── main.jsx
│ │ ├── Dockerfile
│ │ ├── nginx.conf
│ │ └── package.json
│ └── README.md # Web UI documentation
├── assets/
│ └── logos/ # RT tomato/popcorn logos
├── examples/ # Example scripts
├── docker-compose.yml # Docker Compose configuration
├── .env.example # Environment variables template
├── config.example.json # CLI configuration example
└── README.md
# Options: 'northwest', 'northeast', 'southwest', 'southeast'
manager.process_library(position='northwest')The badge automatically:
- Scales to 45% of poster width
- Uses semi-transparent black background (50% opacity)
- Left-aligns all logos
- Displays gold ratings with white symbols
- Adjusts logo sizes (popcorn icons 1.2–1.3x larger for visibility)
Place PNG files in assets/logos/:
tmdb.png— TMDB logoimdb.png— IMDb logort_fresh.png— Fresh tomato (critic ≥60%)rt_rotten.png— Rotten splat (critic <60%)rt_audience_fresh.png— Fresh popcorn (audience ≥60%)rt_audience_rotten.png— Spilled popcorn (audience <60%)
Logos should have transparent backgrounds (PNG with alpha channel).
manager = PlexPosterManager(
plex_url=config['plex']['url'],
plex_token=config['plex']['token'],
library_name='TV Shows', # Change to TV library
...
)
manager.process_library()# Reprocess all items, even if already done
manager.process_library(force=True)# Test on first 10 movies
manager.process_library(limit=10)# IMPORTANT: Use a persistent location, NOT /tmp!
manager = PlexPosterManager(
...,
backup_dir='/home/user/kometizarr/backups' # Or any persistent path
)- Original posters saved to
backup_dir/LibraryName/MovieTitle/ - Web UI/Docker: Backups stored in
./data/backups/(persistent across reboots) - CLI: Default is
/tmp/kometizarr_backups—⚠️ WARNING: This gets cleared on reboot! Use a persistent location for production - Metadata stored (TMDB ID, IMDb ID, ratings)
- Overlay version also saved for reference
- Restore from backed up originals via Web UI or CLI
- Safe to run multiple times
- No data loss
manager = PlexPosterManager(..., dry_run=True)
manager.process_library() # Preview without applying- Multi-source rating badges (TMDB, IMDb, RT Critic, RT Audience)
- Dynamic RT logo system
- Batch processing for movies and TV shows
- Automatic backups and restoration
- Beautiful overlay design with proper alignment
- Rate limiting and API safety
- Collection management (decades, studios, keywords, genres)
- Web UI — React dashboard with FastAPI backend
- Real-time progress — WebSocket updates for live tracking
- Docker deployment — Docker Compose support
- Smart library detection — Auto-detect movie vs TV show libraries
- Network/Studio presets — 13 streaming services + 12 movie studios
- Collection visibility controls — Hide collections from library view
- Cancel/Stop Button — Gracefully abort running processing
- Rating source filtering — Choose which rating sources to display per run
- Browser reconnection — Resume monitoring after page refresh
- WebSocket auto-reconnect — Resilient real-time updates
- 4-Badge Independent Positioning (v1.1.1) — Each badge placed and styled separately
- Visual alignment guides — Live grid overlay for precise placement
- 11 font choices — DejaVu Sans/Serif/Mono in Bold/Regular/Italic
- Live poster preview (v1.2.0) — Render real posters before committing
- Font & logo size sliders (v1.2.0) — Fine-tune badge scale visually
- Scheduled processing (v1.2.0) — Two independent cron jobs (normal + force reprocess)
- Plex Webhook (v1.2.0) — Process new items automatically the moment they're added
- Multi-library selection (v1.2.0) — Checkbox selection for cron, webhook, and dashboard
- Settings tab (v1.2.0) — Full automation config in the Web UI, persisted across restarts
- Webhook/cron badge fix (v1.2.1) — Webhook and cron now use the badge style & positions configured in the UI (defaults to 4-corner layout on first run)
- Per-episode ratings for TV shows — Season/episode level overlay support
- unRAID Community Applications — Official unRAID template for one-click installation
- Multi-server support — Add/remove Plex servers from Web UI
Contributions welcome! Please:
- Open an issue first to discuss changes
- Follow existing code style
- Add tests for new features
- Update documentation
MIT License — See LICENSE file for details.
- Posterizarr — Original overlay inspiration
- Kometa — Collection management patterns
- PlexAPI — Excellent Python Plex library
- MDBList — RT ratings API
- TMDB — Movie database and ratings
- Issues: https://github.com/P2Chill/kometizarr/issues
- Discussions: https://github.com/P2Chill/kometizarr/discussions
Made with ❤️ for the Plex community





