███╗   ██╗██╗   ██╗ ██████╗
 ████╗  ██║██║   ██║██╔════╝
 ██╔██╗ ██║██║   ██║██║  ███╗
 ██║╚██╗██║╚██╗ ██╔╝██║   ██║
 ██║ ╚████║ ╚████╔╝ ╚██████╔╝
 ╚═╝  ╚═══╝  ╚═══╝   ╚═════╝

~ seamless navigation between your window manager and applications — without plugins

about

nvg is a drop-in replacement for your window manager's focus command. It walks the focused window's process tree, lets the innermost supported app (nvim → tmux → wm) move first, and only bubbles up when an app is at its edge.

One binary. No plugins. No IPC config. Auto-detects window manager.

window A · sway
tmux
nvim ~/notes.md
split 1
split 2
shell
$ tail -f log
...
window B · sway
tmux
shell
$ ls -la
...
nvim ~/main.zig
split 1
split 2

install

# linux amd64 / arm64 / armv7
curl -Lo nvg https://github.com/heppu/nvg/releases/latest/download/nvg-linux-amd64
chmod +x nvg
sudo mv nvg /usr/local/bin/

setup

· · · · ·

auto-detected via SWAYSOCK · edit ~/.config/sway/config and replace every focus binding with exec nvg.

bindsym $mod+h exec nvg left
bindsym $mod+j exec nvg down
bindsym $mod+k exec nvg up
bindsym $mod+l exec nvg right

auto-detected via I3SOCK · same IPC as sway · edit ~/.config/i3/config.

bindsym $mod+h exec nvg left
bindsym $mod+j exec nvg down
bindsym $mod+k exec nvg up
bindsym $mod+l exec nvg right

auto-detected via HYPRLAND_INSTANCE_SIGNATURE · edit ~/.config/hypr/hyprland.conf and replace your movefocus bindings.

bind = $mod, h, exec, nvg left
bind = $mod, j, exec, nvg down
bind = $mod, k, exec, nvg up
bind = $mod, l, exec, nvg right

auto-detected via NIRI_SOCKET · edit ~/.config/niri/config.kdl.

binds {
    Mod+H { spawn "nvg" "left"; }
    Mod+J { spawn "nvg" "down"; }
    Mod+K { spawn "nvg" "up"; }
    Mod+L { spawn "nvg" "right"; }
}

auto-detected via XDG_CURRENT_DESKTOP=river · add these bindings to ~/.config/river/init.

riverctl map normal Super H spawn 'nvg left'
riverctl map normal Super J spawn 'nvg down'
riverctl map normal Super K spawn 'nvg up'
riverctl map normal Super L spawn 'nvg right'

auto-detected via DWM_FIFO · requires the dwmfifo patch and xdotool. Export DWM_FIFO=/tmp/dwm.fifo (or pass --wm dwm).

// config.h
static const char *nvg_left[]  = { "nvg", "left",  NULL };
static const char *nvg_down[]  = { "nvg", "down",  NULL };
static const char *nvg_up[]    = { "nvg", "up",    NULL };
static const char *nvg_right[] = { "nvg", "right", NULL };

static const Key keys[] = {
    { MODKEY, XK_h, spawn, {.v = nvg_left}  },
    { MODKEY, XK_j, spawn, {.v = nvg_down}  },
    { MODKEY, XK_k, spawn, {.v = nvg_up}    },
    { MODKEY, XK_l, spawn, {.v = nvg_right} },
};