Library / SDK
fscorrupt/posterizarr avatar
fscorrupt/posterizarr

Posterizarr: textless artwork and overlays for Plex, Jellyfin and Emby

🖼️ Automated asset maker for Plex, Jellyfin & Emby.

936 stars39 forksJavaScriptGPL-3.0

At a glance

What is it?
Posterizarr is a PowerShell script with a web UI that generates poster, fanart and clearlogo assets for media servers, pulling textless images from Fanart.tv, TMDB, TVDB, Plex and IMDb and applying custom overlays. It fits an *arr user who wants artwork refreshed on a schedule, and it is a poor fit for a library that wants no outbound requests and no telemetry.
Who is it for?
Adopt Posterizarr when you run one of the three supported media servers and want artwork collected from several sources, textless versions preferred, with your own text and overlays applied consistently across a library.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Artwork for media libraries, built from textless sources and your own overlays

Posterizarr is a PowerShell script with a full web UI that automates generating images for a media library. The stated purpose is to automate the creation of assets for Plex, Jellyfin and Emby, and the workflow is not just a poster download. It fetches artwork from Fanart.tv, TMDB, TVDB, Plex and IMDb, it focuses on textless images, and it applies custom overlays and text of your own.

That combination is the point of the project. A library that has grown from scraped metadata usually ends up with images carrying baked-in titles, wrong language text, or the artwork of a different release. Fetching textless art and then drawing the title yourself is a different operation, and it is the operation this tool performs.

The code base reflects the mix: the main script is Posterizarr.ps1 with modules alongside it, while the web interface lives in the webui directory and the project is described as JavaScript-based on that side. The repository topics list arr, assets and imagemagick, which names the image processing tool in the chain.

The web UI covers settings, activity and manual logo replacement

The web UI is the interface the project leads with. It lets you manage settings, monitor activity and trigger runs from a browser, and it also handles logo management, where you can search for a clearlogo, preview it and replace one manually.

That last feature is the reason some people will not need the automatic path at all. Automating a logo means trusting the title matching, and when it picks the wrong variant you want to swap in your own file and keep going. The manual replacement path covers that case.

The UI is optional in the container, since the compose file carries a commented DISABLE_UI switch, and the script can also run on its own, which is what the RUN_TIME=disabled environment entry in the example compose file suggests. Running headless is therefore a supported configuration rather than an accident, and the compose file also carries ARR_WAIT_TIME with a default of 300 seconds, described as the time Posterizarr waits for the media server to be ready before starting its own startup process.

Five artwork sources and a PowerShell module doing the Fanart.tv calls

The source list is the breadth of the tool: Fanart.tv, TMDB, TVDB, Plex and IMDb. Textless images are the focus, which matters because each of those services offers different tiers of artwork, and only some carry the plain background or logo variants that a custom overlay needs.

The Docker image shows how the Fanart.tv side is handled. The final runtime stage is python:3.13-alpine, and the image installs PowerShell, ImageMagick from the Alpine edge repository, fontconfig, librsvg and the heic, jpeg and webp ImageMagick variants, plus catatonit, curl, bash, shadow and git.

dockerfile
    && apk add --no-cache \
        catatonit \
        fontconfig \
        imagemagick@edge \
        imagemagick-libs@edge \
        powershell \

After the packages are in place, the image registers PSGallery as a trusted repository and installs a module called Celerium.FanartTV for all users.

dockerfile
        Register-PSRepository -Default; \
        Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction Stop; \
        Install-Module -Name Celerium.FanartTV -Scope AllUsers -Force -ErrorAction Stop; \

So the artwork pipeline runs inside PowerShell, on top of ImageMagick, with fonts registered through fontconfig. The FONTS_GID=5555 environment variable and the non-root mode flag in the image show that font availability and user permissions were deliberate concerns rather than afterthoughts.

Four mounted paths define what a Posterizarr container owns

The example compose file in the repository is the clearest statement of the deployment contract.

yaml
    image: "ghcr.io/fscorrupt/posterizarr:latest"
    restart: "unless-stopped"
    user: "1000:1000"
    ports:
      - "8000:8000" # if you want to change the port inside container, also change APP_PORT env variable

Four host paths are mounted read-write, and each one has a distinct job.

yaml
    volumes:
      - "/opt/appdata/posterizarr:/config:rw"
      - "/opt/appdata/posterizarr/assets:/assets:rw"
      - "/opt/appdata/posterizarr/assetsbackup:/assetsbackup:rw"
      - "/opt/appdata/posterizarr/manualassets:/manualassets:rw"

Config holds the settings, assets is where generated images land, assetsbackup is where replaced artwork is kept, and manualassets is where your own clearlogos live. The backup mount is the one that matters operationally, since a run that overwrites an existing poster needs somewhere to put the old file.

Two details in the compose file deserve attention. The container runs as user 1000:1000 and the image sets a non-root flag, so the mounted directories have to be writable by that uid on the host. The tag is latest, which means a compose pull will move you to a different build without any change on your side.

Kometa compatible folders and triggers from the *arr tools

Posterizarr is built for a specific ecosystem rather than for media servers in general. The output is organised in a Kometa-compatible folder structure, which is what allows a later Kometa run to move the artwork it wants to keep without fighting your layout.

The other half of that fit is triggering. Runs can be started from Tautulli, Sonarr and Radarr, so artwork generation happens when a new item is added rather than on a timer you have to schedule yourself. That design has a practical effect on how the tool behaves: it tends to be invoked in bursts after a library import, and each invocation inherits whatever credentials and configuration the calling tool had.

The alternative approach to the same job is a batch ImageMagick script run from cron, which downloads an image and renames it into place. The difference is not the image processing, which is the same kind of work, but the surrounding layer: Posterizarr adds a settings UI, an activity log, multiple sources with textless preference, your own overlays, backups of replaced files and a trigger path that ties artwork to library changes. The trade is that you now depend on the container image and its configuration file rather than on a script you can read in one sitting.

Telemetry is on by default from v2.2.50 and the payload is four fields

Since v2.2.50, the project collects anonymous basic usage statistics, and the stated purpose is to guide development, such as knowing whether to prioritize Docker or bare-metal, or Plex over Jellyfin.

The payload is stated as exactly four items: an anonymous GUID, the OS, the target media server and the app version. The documentation states that no IP addresses, no personal data and no file paths are collected or stored. A telemetry worker script is part of the repository at telemetry-worker/worker.js.

Opting out is a single setting.

json
"telemetry": false

That value goes in config.json, and the example configuration file config.example.json in the repository root is the starting point for it. For a home lab this is a reasonable trade. For a shared or corporate deployment, the useful thing to check is not the promise but the switch, because the default is on and the payload travels with every run.

Release detection depends on two files staying in sync by hand

The update mechanism is unusual enough to describe, because it explains how versions are handled in this project. The contributing rules ask that every pull request adjust the version number in the script on line 78, and adjust the version number in Release.txt to match the one in the script. The reason given is that the script checks Release.txt to see whether a newer version is available.

So the update check is a comparison against a file in the working tree, and keeping that comparison meaningful is a manual task attached to every pull request, with a note in the documentation that version synchronisation is critical for update detection. The example given in that rule still shows a version string of 3.0.0, while the most recent tag is 3.3.7, so treat the exact line the script reads as something to check in your own checkout rather than assume it.

The cadence itself is brisk. The last push was on 2026-10-19, and the three most recent releases are 3.3.7 from 2026-10-05, 3.3.6 from 2026-09-28 and 3.3.5 from 2026-09-21. The licence is GPL-3.0, which for a script people modify in place is a factor to keep in mind, and the author notes openly that AI is used as a coding assistant for the UI and web components, with every line reviewed and tested before it is committed.

Editorial conclusion

Adopt Posterizarr when you run one of the three supported media servers and want artwork collected from several sources, textless versions preferred, with your own text and overlays applied consistently across a library. Do not adopt it if your policy forbids outbound telemetry, because collection starts by default at v2.2.50 and requires an explicit change in config.json, and think again if you need reproducible builds, because the release tag is not the same thing as the image tag ghcr.io/fscorrupt/posterizarr:latest. Before the first run, read the installation pages on the project documentation site, since the README no longer contains setup steps, confirm the four mounted paths on the host match your media library layout, and check Release.txt against the version string in the script, since the script compares those two files to decide whether an update exists.

Frequently asked questions

How do I install Posterizarr?

The README no longer contains installation steps and points to the project documentation site, with the installation page at the installation section of that site. The repository also ships a Dockerfile and a docker-compose.yml, plus badges for Docker, Unraid, Linux, Windows, MacOS and ARM, so a container deployment is the documented starting point.

Where does Posterizarr get its posters and clearlogos?

It fetches artwork from Fanart.tv, TMDB, TVDB, Plex and IMDb, focusing on textless images, and then applies your own overlays and text. The container image installs the Celerium.FanartTV PowerShell module from PSGallery for the Fanart.tv calls.

Does Posterizarr collect telemetry and how do I disable it?

Since v2.2.50 the project collects anonymous usage stats consisting of an anonymous GUID, the OS, the target media server and the app version, with no IP addresses, personal data or file paths. You opt out by setting "telemetry": false in the config.json file.

Can Posterizarr run alongside Kometa and the *arr apps?

Yes. Output is organised in a Kometa-compatible folder structure, and runs can be triggered from Tautulli, Sonarr and Radarr. The compose file also exposes an ARR_WAIT_TIME setting, defaulting to 300 seconds, which is how long the tool waits for the media server to be ready before starting its own startup process.

What licence is Posterizarr released under?

The licence field on the repository says GPL-3.0, and the LICENSE file at the repository root holds the text. The project is at version 3.3.7 as of the release dated 2026-10-05.

Official sources

  1. fscorrupt/posterizarr on GitHub
  2. License: GPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/fscorrupt-posterizarr.svg)](https://hysenlabs.com/projects/fscorrupt-posterizarr)

Was this useful?