Configuring monitors in Hyprland means writing monitor= lines by hand. A 4K display at 1.33x 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 to get the y-offset right. You reload, you’re off by 40 pixels, you edit, you reload again. There’s no visual feedback until after you’ve committed to a config.
Then it gets worse. You unplug your laptop, go to a conference, plug into a projector, and you’re back to editing config files backstage before your talk. You come home, dock the laptop, and the layout is wrong again.
I looked at what was available. The closest to what I wanted was Monique: spatial editor, profiles, workspace management, a hotplug daemon. It does exactly what I need. But it’s a GTK4 GUI that pulls in Python and a stack of dependencies, and the daemon was broken when I tried it. The other tools each cover parts of this: kanshi does profiles and auto-switching but has no editor, you write config files; nwg-displays and HyprMon have spatial editors but no daemon; HyprDynamicMonitors has a daemon but no real layout tool, and it pulls in UPower and D-Bus.
I wanted Monique’s feature set without the dependency baggage, in something that works over SSH when your monitors are broken. So I built hyprmoncfg.
A real spatial editor, in your terminal
The TUI is the thing I’m most proud of. It’s not a config editor with a preview pane. It’s a full spatial layout tool.
The left side is a canvas where your monitors are drawn as rectangles, proportional to their resolution. You click one to select it, drag it to move it. Monitors snap to each other’s edges as you position them, just like arranging windows in a GUI display manager. Arrow keys give you fine control: 100px per step, Shift for 10px, Ctrl for 1px.
The right side is a per-monitor inspector. Pick a resolution and refresh rate from a scrollable list. Set scale, position, transform, VRR, mirroring. All inline, no dialogs within dialogs. A third tab handles workspace planning.
And because it’s a TUI: it works over SSH. When your monitor configuration is broken and you can’t see anything, you can SSH into the machine and fix it. Try that with a GTK app.
Safe apply with automatic revert
Every apply, whether from the TUI or the daemon, follows the same path: write monitors.conf atomically (temp file + rename, no corruption), reload Hyprland, re-read the actual monitor state, and verify the result matches what was requested.
Then it gives you 10 seconds to confirm. If you don’t, maybe because the layout left you staring at a black screen, it reverts automatically. No stuck monitors. No reaching for a second machine to undo the damage.
This is the same apply engine everywhere. The TUI and the daemon share identical code. If it works when you test it interactively, it works when the daemon fires at 2am because you bumped your dock cable.
Workspace planning
Monitor configuration and workspace assignment are the same problem. If you’re rearranging monitors, you probably want workspaces to follow. hyprmoncfg has a workspace planner built into its third tab, with three strategies:
- Sequential: Groups in chunks. Workspaces 1-3 on monitor A, 4-6 on monitor B.
- Interleave: Round-robins. 1→A, 2→B, 3→A, 4→B.
- Manual: Explicit per-workspace rules when you want full control.
Workspace assignments are stored inside each profile and applied together with the layout. Switch profiles, switch workspace distribution. One operation.
Source-chain verification
Here’s something no other tool does. Before writing anything, hyprmoncfg parses your hyprland.conf and verifies it actually sources the target monitors.conf. If it doesn’t, it refuses to write.
Other tools skip this check. They silently update a file that Hyprland never reads. You spend twenty minutes debugging why nothing changed, only to realize the file was never sourced. I lost an evening to this once. Never again.
Dotfiles integration
Profiles are stored as JSON files in ~/.config/hyprmoncfg/profiles/, one per profile. The generated monitors.conf is a build artifact, you don’t commit it. You commit the profiles.
chezmoi add ~/.config/hyprmoncfg
Save a “desk” profile at home with your ultrawide. Save “conference-1080p” at one venue. Save “conference-4k” at another. Sync them across machines via your dotfiles. The daemon matches profiles to connected hardware automatically. Arrive somewhere, plug in, and the right layout applies.
This is portable. The same profile library works across machines because matching is based on the monitors you have, not on the machine you’re at.
One runtime dependency: Hyprland
Two compiled Go binaries. No Python, no GTK, no GObject introspection, no D-Bus, no UPower. Install them and you’re done. The only runtime requirement is Hyprland itself.
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 |
| Source-chain verification | Yes | No | No | No | No | No |
| Additional runtime dependencies | None | Python + GTK4 + libadwaita | UPower, D-Bus | None | Python + GTK3 | None |
Try it
On Arch:
Or build from source:
go install github.com/crmne/hyprmoncfg/cmd/hyprmoncfg@latest
go install github.com/crmne/hyprmoncfg/cmd/hyprmoncfgd@latest
Check out the documentation for the full guide, or browse the source on GitHub.