Omahub
← All plugins
3

Omarchy Plex

by 3x3q

A full Plex player for Omarchy: sidebar library browsing, detail pages, theater + minibar playback, picture-in-picture floaty mode, audio/subtitle track selection, and keyboard-first navigation throughout.

Security review

Review recommended · 4 findings

Deterministic scan — not a security guarantee

Medium
Risk level
Medium
Analyzed commit
1a69c0b
Scanned
1 month ago
  • Command runs with sudo, elevating the process beyond the plugin environment.

    sudo for the final install into /usr/lib/qt6/qml/.
  • Command runs with sudo, elevating the process beyond the plugin environment.

    sudo cmake --install build
  • Docs external_hosts README.md:56

    Downloads or connects to an external HTTP(S) host.

    git clone https://github.com/dot3x3q/omarchy-plex
  • Command runs with sudo, elevating the process beyond the plugin environment.

    sudo cmake --install build

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
1a69c0b
Reviewed
1 month ago

The plugin is a Plex client with notably careful handling of the Plex token: bounded/atomic config writes, header-based auth for API calls, input validation, and a documented fallback architecture. The deterministic scan's medium findings reduce to the README's clone example and the explicit, user-invoked `sudo` step in the optional native installer, not to hidden or automatic elevation. No obfuscated code, persistence tricks, or destructive install-time behavior was found in the sampled sources.

  • The optional native installer (`native/install.sh`) runs `sudo cmake --install` and writes to `/usr/lib/qt6/qml`; this is transparent and opt-in, but it is the main reason the scan reports medium and should be clearly surfaced to users.
  • The external mpv backend passes the Plex token via mpv argv, making it readable through `/proc/<pid>/cmdline` by same-user processes; the README documents this and the native module avoids it, but it is a real credential-exposure consideration.
  • Image URLs place the X-Plex-Token in the query string because QML `Image` cannot send headers; this is a documented exception and only goes to the user-configured Plex server.
  • The external host finding is documentation-only (`git clone` in README) and not part of the executable plugin flow.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/dot3x3q/omarchy-plex --enable
Widgets #bar #quickshell #media

omarchy-plex

CI

A Plex media player for Omarchy. Real window in the tiling tree, library browsing, poster grids, a proper theater view, and a picture-in-picture mode that can be resized and plopped on additional monitors.

I wanted a Plex player that was lightweight, performant, and true to the Omarchy theme, so I built this player exactly as I wanted it. Use it, tweak it, and upgrade it as you like!

omarchy-plex

<p align="center"> <img src="screenshots/Player.png" width="49%" alt="Theater playback"> <img src="screenshots/PiP.png" width="49%" alt="Picture-in-picture"> </p> <p align="center"> <img src="screenshots/Search.png" width="49%" alt="Search"> <img src="screenshots/Settings.png" width="49%" alt="Settings"> </p>

What you get

  • Media Browser — Home page with Continue Watching and Recently Added shelves, a sidebar entry per video library, poster grids, and detail pages with backdrop art, synopsis, and season/episode drill-down. Movies and TV only; your music stays in your music player.
  • Search everything — / from anywhere, whole server, results as you type.
  • Theater + minibar — video fills the window with controls that get out of the way. Hit Esc and it keeps playing behind a now-playing bar while you browse for what's next.
  • PiP — p pops the video into a corner card that floats above everything and is click-through everywhere else. Drag it anywhere (it shows you exactly where it'll land, even across monitors), snap it to corners, resize it, walk it across displays with n. Esc brings it home.
  • Real playback — with the optional native module, video renders through libmpv: hardware decode, proper HDR tone mapping (your dark scenes will stop looking crushed), and image subtitles (PGS/VOBSUB) rendered natively instead of via server burn-in.
  • Tracks and quality — a/s/q mid-playback for audio tracks, subtitles, and stream quality. Direct-play switches are instant; anything needing the server restarts at your position.
  • Volume to 200% — for those movies mixed by people who hate you.
  • Keyboard-first — arrows and hjkl drive one shared cursor; the whole app works without a mouse. Full reference below.
  • Bar widget — the icon grows a scrolling now-playing title while something plays. Click toggles the window.
  • Resume, progress sync, and scrobbling all work like you'd expect — Plex knows where you stopped, whatever client you open next.

Install

git clone https://github.com/dot3x3q/omarchy-plex
ln -s "$(pwd)/omarchy-plex" ~/.config/omarchy/plugins/dot3x3q.omarchy-plex
omarchy restart shell

Then add the bar widget from Omarchy's bar settings, or just toggle the panel directly:

omarchy-shell shell toggle dot3x3q.omarchy-plex

The native video module (recommended)

Out of the box, video renders through QtMultimedia — works fine, zero extra steps. But the good stuff (HDR tone mapping, NVDEC/VAAPI hardware decode, native image subtitles) comes from a small compiled libmpv module:

./native/install.sh
omarchy restart shell

That's it — the plugin detects the module and upgrades itself. No module, no problem: it falls back to QtMultimedia automatically, always. (This fallback is permanent by design — the module is OpenGL-only, so a shell forced onto the Vulkan scene graph would need it. See native/README.md.)

Setup

First open drops you on a setup page:

  1. Server URL — http://your-server:32400
  2. X-Plex-Token — Plex's guide: finding your token
  3. Backend — leave it on "In panel" unless you specifically want playback in an external mpv window

Config lands in ~/.config/omarchy-plex/config.json, chmod 600, written atomically. The token travels in request headers wherever technically possible; the exceptions (image URLs, QtMultimedia media URLs — neither can send headers) are documented in docs/DESIGN.md. The native module sends it header-only, which is one more reason to build it.

The two surfaces

The window is a real Hyprland toplevel — tile it, float it, fullscreen it. Drag any bare part of it to move it; the edges resize. This is where browsing lives.

The PiP is video only, on purpose. It floats above everything, ignores your clicks everywhere except the card itself, and gets out of your way. When you drag it toward another monitor it pins at the border and paints a ghost outline where it'll drop — release and it's there, still playing.

Keeping the window fully opaque

Omarchy's default window rules make every unfocused window slightly translucent. For most apps that looks great; for a movie it doesn't. Add this to ~/.config/hypr/hyprland.lua to opt the player out (the same idiom Omarchy's stock rules use for mpv-style PiP and qemu):

o.window({ class = "^org\\.quickshell$", title = ".*Omarchy Plex$" }, {
  tag = "-default-opacity",
  opacity = "1 1",
})

Match by title, not class alone: the window's class is org.quickshell, shared with the entire shell. The leading .* is required — Hyprland regexes must match the whole string, and during playback the title becomes "<media> — Omarchy Plex", so a bare Omarchy Plex$ silently stops matching the moment something plays.

Keyboard reference

One cursor, shared by mouse and keyboard. Everything below has a mouse equivalent.

Browsing

Key Action
↑ ↓ ← → / h j k l Move the cursor
Tab / Shift+Tab Cycle region (search → page → sidebar → minibar)
/ Focus search
Enter Open / play / run search
Esc Layered: clear search → leave field → exit theater → back → arm close → close
Alt+Left Back
PageUp / PageDown Page the view
r Refresh
p Toggle PiP
Space Play/pause, globally, whenever something's playing
m Mute, likewise

While playing (theater / PiP)

Key Action
Space / Enter Play / pause
← / →, Shift+← / Shift+→ Seek 10s / 30s
↑ / ↓ Volume ±5 (0–200%)
m Mute
x Stop
a / s / q Audio / subtitle / quality picker (window only)
p Toggle PiP
n / Shift+n Walk the PiP across monitors
Esc PiP → window; theater → browse (keeps playing)

Pickers (once open)

↑↓/jk move, Home/End jump, Enter selects, a/s/q switch lists, Esc closes.

Hacking on it

  • docs/DESIGN.md — the design spec: every decision and why.
  • docs/PLEX-API.md — every Plex endpoint used, verified against a live server.
  • AGENTS.md — dev-loop commands (lint, tests, the compile gate that catches what the linter can't).
  • node --test tests/*.test.mjs — Api mappers, IO safety, and static contract pins over the QML.

Pull requests

CI runs the unit tests on node 22/24/26 and compiles every *.qml with qmlcachegen, so a PR gets checked without needing me at a keyboard. Two things CI can't do for you, because they need Omarchy itself rather than a container:

  • run qmllint against the shell's qs.Commons / qs.Ui types, and
  • actually load the plugin on a compositor.

So if a change touches QML behaviour rather than plain logic, say in the PR whether you ran it on a real Omarchy session. I'd rather know it's untested than assume it isn't.

Removing

rm -rf ~/.config/omarchy-plex ~/.local/state/omarchy-plex
rm ~/.config/omarchy/plugins/dot3x3q.omarchy-plex

Credit

This project started life as a fork of Joshua Warren's omarchy-plexmini, a deliberately tiny bar-summoned miniplayer. It has since been rebuilt into something else entirely, but the foundation — the Plex API plumbing and the genuinely careful security posture around the token — is his work, and this project wouldn't exist without it. Go star the original.

License

MIT — see LICENSE, which carries both copyrights.