hyprmoncfg is a terminal layout editor, CLI, profile store, and hotplug/lid-aware daemon for Hyprland monitor setups. Drag displays into place, save hardware-aware profiles, apply them safely, and let the daemon switch profiles when monitors or your laptop lid changes.

What you get
- Spatial layout editor -- drag monitors on a canvas and tune mode, scale, VRR, mirror, transform, and exact position
- Named profiles -- save setups like
desk, conference, or home-office
- Hardware-identity matching -- profiles follow monitor make, model, and serial instead of unstable connector names
- Hotplug and lid-aware daemon -- apply the right profile automatically when monitors change or the laptop lid closes
- Workspace planner -- assign workspaces across monitors with sequential, interleave, or manual strategies
- Safe apply with revert -- reload Hyprland, verify the result, and revert unless you confirm
- One-writer IPC -- when the daemon is running, the TUI, CLI, and desktop panels send changes through it instead of racing over config files
- Include-chain verification -- refuse to write generated monitor config that Hyprland is not reading
- Hyprland 0.55 Lua config support -- use
monitors.lua automatically when hyprland.lua is active, while preserving legacy monitors.conf setups
- One hard runtime dependency -- Hyprland; UPower is optional for immediate lid events
Install
Arch Linux:
yay -S hyprmoncfg
# or
yay -S hyprmoncfg-git
Fedora COPR:
sudo dnf copr enable paolino/hyprmoncfg
sudo dnf install hyprmoncfg
Nix / NixOS:
nix run nixpkgs#hyprmoncfg
nix profile install nixpkgs#hyprmoncfg
Gentoo GURU:
sudo eselect repository enable guru
sudo emaint sync -r guru
sudo emerge gui-apps/hyprmoncfg
Void Linux, via the unofficial Blackhole-vl repo:
printf 'repository=https://mirror.black-hole.dev/%s/\n' "$(uname -m)" | sudo tee /etc/xbps.d/00-repository-blackhole.conf
sudo xbps-install -S
sudo xbps-install -S hyprland hyprmoncfg
Build from source:
git clone https://github.com/crmne/hyprmoncfg.git
cd hyprmoncfg
go build -o bin/hyprmoncfg ./cmd/hyprmoncfg
go build -o bin/hyprmoncfgd ./cmd/hyprmoncfgd
install -Dm755 bin/hyprmoncfg ~/.local/bin/hyprmoncfg
install -Dm755 bin/hyprmoncfgd ~/.local/bin/hyprmoncfgd
Distro packagers should use PACKAGING.md.
For legacy configs, make sure ~/.config/hypr/hyprland.conf sources monitors.conf:
source = ~/.config/hypr/monitors.conf
For Hyprland 0.55+ Lua configs, include monitors.lua from hyprland.lua, for example with pcall(require, "monitors"). hyprmoncfg verifies legacy source chains before writing; for Lua, it reloads Hyprland and asks the active Lua state to confirm that the generated monitor file actually ran. Existing files without hyprmoncfg's first-line ownership marker are protected: interactive use asks before replacing them, and the daemon refuses.
Create your first profile
hyprmoncfg
Drag monitors into place, press s, type a profile name like desk, and press Enter.
Apply it later from the CLI:
hyprmoncfg apply desk
Enable automatic switching
AUR, Fedora COPR, Nixpkgs, and Gentoo GURU:
systemctl --user daemon-reload
systemctl --user enable --now hyprmoncfgd
Void Linux with Blackhole-vl:
exec-once = hyprmoncfgd
Manual install:
mkdir -p ~/.config/systemd/user
cp packaging/systemd/hyprmoncfgd.local.service ~/.config/systemd/user/hyprmoncfgd.service
systemctl --user daemon-reload
systemctl --user enable --now hyprmoncfgd
The daemon scores every profile in ~/.config/hyprmoncfg/profiles/, so delete throwaway profiles before relying on automatic switching.
On Omarchy versions that launch omarchy-hyprland-monitor-watch, hyprmoncfgd stops that exact transient user scope while it owns monitor profiles and restores the watcher when the daemon exits during a live Hyprland session. Generated configuration used without the daemon cannot provide this runtime ownership; static-config users must disable the Omarchy watcher separately.
When the daemon is running, it is the canonical monitor-config writer. The TUI, CLI, and desktop integrations use its versioned Unix-socket IPC; when it is absent, the TUI and CLI keep working through the same core engine in direct mode. A profile selected interactively stays selected until the next monitor hotplug or lid change, when automatic matching resumes.
Screenshots
hyprmoncfg adapts to your theme. Here are some examples:
| Layout editor |
Save dialog |
 |
 |
Why it exists
Configuring monitors in Hyprland means writing monitor= lines by hand. A 4K display at 1.33333x scale is effectively 2880x1620 pixels, so the monitor next to it needs to start at x=2880. Vertically centering a 1080p panel against it means doing division in your head, reloading, noticing the layout is wrong, and editing again.
It gets worse when setups change:
- No visual editor. You write
monitor= lines by hand and hope the coordinates are right.
- No profiles. Desk, projector, travel, and docked setups all need different layouts.
- No automatic switching. Hotplug a monitor and Hyprland guesses again.
- Connector names are unstable.
DP-1 and DP-2 can swap between boots.
- Some tools pull in too much. Python, GTK, and GObject introspection are a lot of stack just to move a rectangle.
How it works
hyprmoncfg ships two binaries:
|
|
hyprmoncfg |
TUI + CLI for layout editing, profile management, and workspace planning |
hyprmoncfgd |
Background daemon that auto-applies the best matching profile on hotplug and lid changes |
Both use the same apply engine:
write monitors.conf -> reload Hyprland -> verify live state -> confirm or revert
There is no separate best-effort daemon path. If the TUI can apply a profile correctly, the daemon uses the same machinery.
Dotfiles integration
Profiles live in ~/.config/hyprmoncfg/profiles/. Each profile has a canonical JSON file plus generated .conf and .lua sidecars you can keep as plain Hyprland snippets if you stop using hyprmoncfg. Add the directory to your dotfile manager and your layouts roam across every machine you own.
With chezmoi:
chezmoi add ~/.config/hyprmoncfg
Now your desk at home, your laptop on the road, and your Raspberry Pi in the closet all share the same profile library. The daemon picks the right one based on what's actually plugged in.
You don't commit the active ~/.config/hypr/monitors.conf or ~/.config/hypr/monitors.lua. You commit your profiles. The tool writes the active generated monitor config for you.
How it compares
|
hyprmoncfg |
Monique |
HyprDynamicMonitors |
HyprMon |
nwg-displays |
kanshi |
| GUI or TUI |
TUI |
GUI |
TUI |
TUI |
GUI |
CLI |
| Spatial layout editor |
Yes |
Yes |
Partial |
Yes |
Yes |
No |
| Drag-and-drop |
Yes |
Yes |
No |
Yes |
Yes |
No |
| Snapping |
Yes |
Not documented |
No |
Yes |
Yes |
No |
| Profiles |
Yes |
Yes |
Yes |
Yes |
No |
Yes |
| Auto-switching daemon |
Yes |
Yes |
Yes |
No (roadmap) |
No |
Yes |
| Workspace planning |
Yes |
Yes |
No |
No |
Basic |
No |
| Mirror support |
Yes |
Yes |
Yes |
Yes |
Yes |
No |
| Safe apply with revert |
Yes |
Yes |
No |
Partial (manual rollback) |
No |
No |
| Hyprland 0.55 Lua config |
Yes |
No |
No |
No |
Yes |
N/A |
| Include-chain verification |
Yes |
No |
No |
No |
No |
No |
| Additional runtime dependencies |
None |
Python + GTK4 + libadwaita |
UPower, D-Bus |
None |
Python + GTK3 |
None |
Docs
Full documentation at hyprmoncfg.dev.
Development
Install the pre-commit hook to run CI checks locally before each commit:
ln -sf "$(pwd)/scripts/pre-commit" .git/hooks/pre-commit
The hook runs go mod tidy, go vet, go test, and go build.
Regenerate demo videos and screenshots:
./scripts/capture_media.sh
The media scripts use the installed hyprmoncfg from PATH.
Regenerate only the GIF and MP4 demo:
./scripts/capture_demo.sh
Regenerate only screenshots:
./scripts/capture_screenshots.sh
License
MIT