Binary Cache:
- Cache: https://cache.ysun.co
- Key:
cache.ysun.co-1:WxPYwT5g3kt9XhUhHPpNLZKI9HIOsVVAuqSHpok8Qt4=
nirimon is a fork of hyprmon (Eran Sandler,
Apache 2.0) that's intended to only work for
Niri just like hyprmon is only build for
Hyprland. All Hyprland specific code paths were stripped but the profile JSON
format is preserved so all existing hyprmon profiles will still work if you copy
~/.config/hyprmon to ~/.config/nirimon. Read more info over at hyprmon's
repository, the feature is basically the same.
Note that unlike hyprmon, niromon does not write to ~/.config/niri/config.kdl
or any other persistent Niri config file. Monitor application is via
niri msg output ... calls, which are runtime-temporary. Niri reload (config
edit, niri msg action load-config-file, or restart) reverts them. Persistence
belongs to the profile json files in ~/.config/nirimon/profiles/.
To run nirimon in an ephemeral environment:
nix run github:stepbrobd/nirimonOr for persistent installation, check how its packaged without gomod2nix in
my own configuration.
Or if you are not using Nix/NixOS, build from source:
git clone --depth=1 https://github.com/stepbrobd/nirimon
pushd nirimon
go build -ldflags="-s -w -X main.Version=$(cat version.txt)"
sudo mv nirimon /usr/local/bin/
popdOr if you must:
go install -ldflags="-s -w -X main.Version=0-unstable-$(date -u +%Y-%m-%d)+go" ysun.co/nirimon@latestBasically the same as hyprmon but a few features are stripped or not yet supported by Niri.
nirimon # main TUI
nirimon profiles # profile selection menu
nirimon -profile <profile> # apply a saved profile directly
nirimon -list-profiles # list profile names (active marked with *)
nirimon -active-profile # print the name of the currently matching profileMain UI:
| Key | Action |
|---|---|
| Arrow keys / hjkl | Move selected monitor by the grid step |
| Shift + arrows | Move by 10x grid step |
| Tab / Shift-Tab | Cycle through monitors |
| G | Cycle grid size (1, 8, 16, 32, 64 px) |
| L | Cycle snap mode (Off, Edges, Centers, Both) |
| R | Open scale picker |
| F | Open mode (resolution + refresh) picker |
| M | Open mirror configuration (needs wl-mirror) |
| C / D | Open advanced display settings dialog |
| Enter / Space | Toggle the selected monitor on/off |
| A | Apply the current layout to niri now |
| Z | Revert to previous configuration |
| O | Open the profiles page |
| P | Save current layout as a named profile |
| ? | Show help |
| Q / Ctrl-C | Quit |
| Action | Effect |
|---|---|
| Left click | Select monitor |
| Left drag | Move monitor (with snapping) |
| Right click | Toggle monitor on/off |
| Scroll wheel | Adjust monitor scale |
Profiles are json files in ~/.config/nirimon/profiles/. They store the full
monitor layout (resolution, refresh, position, scale, transform, vrr, and
EDID-derived identifiers for stable matching across port reassignments).
nirimon -profile home
nirimon -profile work
nirimon -profile docked
nirimon profiles # interactive menuNiri has
no native output mirroring
the way Hyprland does. nirimon keeps hyprmon's mirror picker (press M) and the
exact same profile schema, but applies the mirror by spawning
wl-mirror: for a monitor set to mirror
another, nirimon launches wl-mirror --fullscreen-output <target> <source>,
which captures the source output and shows it fullscreen on the target.
wl-mirror must be on PATH. The Nix package wraps it in automatically; if you
build from source, install wl-mirror yourself. When wl-mirror is missing the
mirror picker still works and the choice is saved to the profile json, but it is
not applied (the picker says so), so a profile stays portable to hyprmon.
Because the mirror is an ordinary fullscreen Wayland window and not a compositor-level clone, it behaves differently from Hyprland's native mirror. Keep these gotchas in mind:
- It is just a fullscreen window on the target output. niri does not pin you to it: you can switch workspaces, focus other windows, or move the wl-mirror window away, and the target stops showing the mirror until you switch back.
- The mirror process is detached and keeps running after nirimon exits (so a
nirimon -profile ...from a keybind or hotplug hook leaves a working mirror). nirimon tracks it in$XDG_RUNTIME_DIR/nirimon/mirrors.jsonand tears it down on the next apply that disables the mirror. It is also cleared on logout, or you canpkill wl-mirrorby hand. - Scaling uses wl-mirror's
fitmode: the whole source is always shown, letterboxed when the aspect ratios differ. wl-mirror cannot aspect-distort to fill the way Hyprland does, so expect black bars on mismatched ratios instead of stretching. - If the source output is unplugged or turned off, wl-mirror exits; re-apply to restart the mirror once the source is back.
- Only active, non-mirrored monitors can be a source, and circular mirrors are prevented, same as hyprmon.
For clamshell-style switching on lid open/close, bind these to your niri keybinds in your niri config:
binds {
Mod+F1 { spawn "nirimon" "-profile" "home"; }
Mod+F2 { spawn "nirimon" "-profile" "work"; }
}