Open-source project
BlueManCZ/hyprmod avatar
BlueManCZ/hyprmod

HyprMod: a GTK4 settings app that previews Hyprland changes live

Native GTK4/libadwaita settings app for Hyprland.

1,113 stars27 forksPythonGPL-3.0

At a glance

What is it?
HyprMod is a native GTK4 and libadwaita front end for Hyprland configuration, built on the hyprland-config, hyprland-schema, hyprland-state, hyprland-monitors and hyprland-socket libraries. It applies edits to the running compositor as you make them, writes only to its own hyprland-gui.conf, and ships a profile command for switching setups from the shell.
Who is it for?
HyprMod fits a Hyprland user who wants to explore compositor options through a real desktop application instead of a config file, and it does not fit a user who treats the config as source code under version control, because the app writes to its own hyprland-gui.conf and leaves the rest of your configuration alone.
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 14 days ago.
What is it written in?
Mainly Python, 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

The app edits a file it owns, not the config you wrote

HyprMod is a native GTK4 and libadwaita settings app for Hyprland. Its pitch in one line is that you can tweak any option, see it change live, and save when you are happy with it.

The important design decision comes immediately after: the configuration you already wrote is left alone, and HyprMod writes only to its own `hyprland-gui.conf`. That single constraint shapes everything else about how the tool behaves. Nothing in your existing file is rewritten, so a rule you hand-tuned by hand is not at risk from a button press in the interface, and the app's own state stays in one predictable place that you can inspect, back up, or delete.

The trade is that the settings live in two places. Your original file keeps its role, and the app's file holds what you changed through the interface. Anyone mixing the two approaches needs to know which file owns a given setting, and the documentation does not walk through how a rule defined in both places resolves. That is the first thing to check on a real setup.

The feature list is broad for a settings app: a bezier curve editor with live animation preview, a monitor layout editor with VRR, 10-bit detection and HDR controls, a keybind editor with interactive key capture including mouse-drag binds, editors for window rules, layer rules and workspace rules, autostart and environment variable management, a cursor theme picker, a pending changes page for reviewing unsaved edits, and global search across all options with Ctrl+F.

Five hyprland libraries do the talking to the compositor

The dependency list in `pyproject.toml` is the clearest statement of the architecture, and it is unusual enough to be worth reading line by line. On top of `pygobject` and `pycairo`, the project depends on `hyprland-config`, `hyprland-schema`, `hyprland-state`, `hyprland-monitors` and `hyprland-socket`.

The dependency names trace the split: configuration, schema, state, monitors and sockets are separate libraries rather than one monolith. HyprMod is a user interface on top of that stack rather than a reimplementation of it, which is why the live preview is achievable at all: a change can be pushed to the running compositor and the resulting state read back.

The `pycairo` entry comes with an explanatory comment in the manifest that is worth repeating to anyone packaging this. PyGObject on PyPI already requires pycairo, but distribution packages of PyGObject list it as optional, and every `DrawingArea` silently draws nothing without it. That is a quiet failure mode: the application starts, and the custom drawn parts of the interface are simply blank.

The rest of the toolchain is conventional. The build backend is hatchling, the entry point is `hyprmod = "hyprmod.main:main"`, the development group pulls in pyright, pytest and ruff, and ruff is configured for a 100 character line length with `py312` as the target version.

Undo with Ctrl+Z and a pending changes page separate preview from persistence

Two features address the same worry, which is that a live preview applies an edit before you are sure you want it.

Undo is per change, with Ctrl+Z stepping back one change at a time. The pending changes page answers the other half of the problem: it lists every unsaved edit so you can review the batch before saving. Together they mean the compositor reflects your experiments while you work, and nothing is written to disk until you commit that batch.

This is the design that makes a live preview acceptable in a compositor at all. A compositor reload is visible and immediate, which is normally a reason to be cautious with a settings editor. Here the caution is handled at two levels: a single edit can be taken back, and the whole set can be reviewed before it becomes permanent.

One more idea in the list is worth calling out for what it is. Profiles are saved, named and shared as `.conf` files, complete configurations that can be switched between, and each profile gets a Config DNA, described as a unique visual fingerprint. Switching profiles is also possible without opening the window, which is the subject of the next section.

hyprmod profile switches setups without the window

There is a command line interface for profile management, and the design intent is that you bind it to a keybind in Hyprland or call it from a script, so switching setups does not require opening the application.

bash
hyprmod profile list            # show saved profiles (active marked with *)
hyprmod profile apply Gaming    # switch to a profile by name (case-insensitive)
hyprmod profile next            # cycle to the next profile (alphabetical, wraps around)
hyprmod profile previous        # cycle to the previous one (alias: prev)

The details in that listing are the interesting part. `list` marks the active profile with an asterisk. `apply` takes a name and is case-insensitive, so a bound key can carry a lowercase name. `next` and `previous` cycle alphabetically and wrap around, which makes a pair of keybinds a quick toggle between two setups without naming either one.

The alphabetical ordering is a small design choice with a real consequence: it means the cycle order is stable across sessions and does not depend on when a profile was created, so a keyboard workflow stays predictable. It also means the order is not something you control directly, so if your most-used profile is in the middle of the list, reaching it by cycling takes a fixed number of presses rather than one.

Installing from a shell script, the AUR, Nix, or uv and pipx

Requirements are stated up front: Python 3.12 or newer, GTK4, and libadwaita. The documentation also warns that HyprMod is in active development and not yet packaged for most distributions, which is why there is a one-line installer that claims to work on any distribution:

bash
curl -LsSf https://raw.githubusercontent.com/BlueManCZ/hyprmod/main/install.sh | sh

The same script removes the installation when passed `--uninstall`:

bash
curl -LsSf https://raw.githubusercontent.com/BlueManCZ/hyprmod/main/install.sh | sh -s -- --uninstall

Piping a remote script into a shell is a real trade-off, and it is the route the documentation presents first, so it is worth understanding what the alternative routes cost you. Arch Linux users get an AUR package with `yay -S hyprmod`, Gentoo users get it through the edgets overlay with `emerge -a hyprmod`, and NixOS and home-manager users add the flake as an input and reference `inputs.hyprmod.packages.${pkgs.stdenv.hostPlatform.system}.default` in `home.packages` or `environment.systemPackages`. There is also a pkgit route, `pkgit -i https://github.com/BlueManCZ/hyprmod`.

If you prefer to drive the install yourself, the documentation shows a uv and a pipx path, and both end with the same step that places the desktop entry and icon:

bash
uv tool install git+https://github.com/BlueManCZ/hyprmod.git
hyprmod --install     # places .desktop + icon under ~/.local/share

The Nix path also lets you work from a local checkout without installing anything system wide, which is the safest way to try it:

bash
git clone https://github.com/BlueManCZ/hyprmod.git
cd hyprmod
nix build .#hyprmod        # build
nix run   .#hyprmod        # run without installing
nix shell .#hyprmod        # shell with hyprmod on PATH

Lua config support raises the minimum Hyprland version

The feature list includes Lua config support, described as migrating and editing `hyprland.lua` directly, and it is marked as requiring Hyprland 0.55 or later. That is a hard floor on the compositor version, and it is worth checking before anything else in this article, because the rest of the application is much less demanding.

The repository layout backs up the Lua story. A `bldit.lua` file sits at the top level, next to `hatch_build.py`, which is the custom hatchling build hook declared in `pyproject.toml`. A Python file and a Lua file sitting together in the root of a GTK application is a strong hint about how the Lua path is wired, and the `data/` directory alongside them is the other place to look for bundled resources.

The version history shows a project moving quickly. v0.3.0 was tagged on 2026-05-25, v0.4.0 on 2026-07-01, and v0.5.0 on 2026-10-07, matching the version in `pyproject.toml`. The last push was on 2026-10-09. At a cadence of roughly one tagged release every two months, with a 0.x version number, the reasonable assumption is that the file format and the option set can change between releases, and that a `0.5.0` written config is not guaranteed to load in `0.4.0`.

Where HyprMod is the wrong tool

The clearest case is a user who keeps their Hyprland configuration in git and treats it as code. A dotfiles repository with a config file, a review process and a rollback through `git checkout` gives you version history, diffs and collaboration, and none of that is in scope for a GTK settings application. A GUI that writes to its own file and offers per-change undo in the app is a different model of ownership: the record of what changed lives in the application's own history rather than in your commits.

There is a second, more practical limit. The requirements are Python 3.12 or newer, GTK4, and libadwaita, and the documentation says outright that the project is not yet packaged for most distributions. A user on a distribution where packaging means assembling the GTK stack and a Python environment by hand is doing more work than the app saves them, and the one-line installer does not remove that requirement, it just automates the last step.

A third limit is the scope of the option set. The editors cover the areas the feature list names, and there is no claim that every Hyprland directive is exposed. Anything the interface does not cover still has to be written by hand in the file you already maintain, so a complete setup ends up split between two places by design rather than by accident.

Against editing the config by hand or writing your own tool

The real alternatives are two, and both are cheaper in different ways.

Editing `hyprland.conf` by hand has no dependencies beyond a text editor, gives complete control over every directive including the ones no interface exposes, and produces a file that is text you can diff and search. What it gives up is the live preview and the guidance: you find out whether a curve or an HDR setting is right by applying it and looking, and a typo shows up as a failed reload rather than as a control that refuses a value.

Writing your own tool is the third option, and the `hyprland-*` dependency list makes it more feasible now than it used to be. Since parsing, schema access, state queries, monitor information and the socket connection all exist as importable libraries, a script that applies a specific change is a much smaller job than it used to be. What you inherit is only what you write, which for a one-off change is often the right amount.

HyprMod is worth the GTK4 and libadwaita dependency when the exploration itself is the goal, when you want to see what a setting does before deciding to keep it, and when the answer to a question is easier to find by moving a slider than by reading a manual and editing text. For a user who already knows exactly what they want, the config file remains the shorter path.

Editorial conclusion

HyprMod fits a Hyprland user who wants to explore compositor options through a real desktop application instead of a config file, and it does not fit a user who treats the config as source code under version control, because the app writes to its own hyprland-gui.conf and leaves the rest of your configuration alone. Before adopting it, check that your Hyprland version is new enough for the Lua support, which the documentation puts at 0.55 and later, and note that the documentation still describes the project as in active development and not yet packaged for most distributions, with install.sh and the AUR as the practical routes.

Frequently asked questions

How do I install HyprMod?

The one-line installer is `curl -LsSf https://raw.githubusercontent.com/BlueManCZ/hyprmod/main/install.sh | sh`, and the same script uninstalls when given `--uninstall`. Arch users can install the AUR package with `yay -S hyprmod`, and NixOS users add the flake as an input. You need Python 3.12 or newer, GTK4 and libadwaita.

Does HyprMod modify my existing Hyprland configuration?

No. The documentation states that your config stays untouched and that HyprMod writes only to its own `hyprland-gui.conf` file.

Can I switch Hyprland profiles without opening the app?

Yes. The CLI provides `hyprmod profile list`, `hyprmod profile apply <name>`, `hyprmod profile next` and `hyprmod profile previous`, and the documentation suggests binding these to a Hyprland keybind or calling them from a script.

What is the minimum Hyprland version for HyprMod's Lua support?

The Lua config support, which migrates and edits `hyprland.lua` directly, is marked as requiring Hyprland 0.55 or later. The rest of the application only states a requirement for Python 3.12 or newer, GTK4 and libadwaita.

Official sources

  1. BlueManCZ/hyprmod on GitHub
  2. Issues
  3. License: GPL-3.0
  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/bluemancz-hyprmod.svg)](https://hysenlabs.com/projects/bluemancz-hyprmod)

Was this useful?