Pick anything.
hjkl-fast.
Vim-modal picker. Rofi replacement.
Seven modes — dmenu, drun, run, ssh, emoji, clipboard, calc — on a real Wayland layer-shell overlay with exclusive keyboard grab. On Windows the same binary opens a regular top-level window. One binary, no daemon, no phone-home.
why
A launcher shaped like a vim picker.
Vim-modal navigation
Normal, Insert and Visual. j/k move. gg/G snap. Ctrl-d/Ctrl-u half-page. / search. : ex command. Count prefixes work — 5j jumps five rows. Insert-entry motions match vim: i, a, A, I.
nucleo matcher
The same fuzzy matcher Helix ships. Match positions highlight inline so you can see why a row scored where it did.
Seven sources, one keymap
dmenu · drun · run · ssh · emoji · clipboard · calc, all behind a single
Mode trait. Pick with --show, or switch live
from the ex line.
floem + layer-shell
Built on
floem
(vello GPU render, reactive views). Layer-shell ships today through
pinned floem + winit forks — real overlay, exclusive zone, exclusive
keyboard grab — while the upstream split (lapce/floem#1077, the menus feature gate) is still open. The
[patch.crates-io] entries come out when both land on
crates.io.
No daemon. No state.
Cold-start picker, exit on accept. No background service. Config is pure TOML, never auto-written, in-memory defaults when absent.
Native, not wrapped
No Qt, no Electron, no web view — floem draws every pixel (GTK3 comes
along transitively for floem's menu backend on Linux). Needs a
compositor advertising wlr-layer-shell-unstable-v1 —
Hyprland, sway, niri, river, wayfire. GNOME Mutter doesn't advertise it;
X11 support was dropped and there is no windowed-fallback flag.
Pipe anything
echo "$(ls)" | pikr --dmenu picks a line. Stdout is clean —
wire pikr into shell pipelines the way you'd wire fzf.
Launches don't leak
Every spawn gets stdin, stdout and
stderr nulled, so the launched app never captures pikr's
file descriptors or scribbles over a dmenu pipeline. pikr exits right
after accept; the child keeps running.
Zero telemetry
No analytics, no update pings, no usage stats. No HTTP client anywhere in the dependency tree. Local config, local defaults.
Frecency + query history
Accepts bump a per-mode counter with half-life decay, so the apps you
actually launch float above equally-matching rows. Queries are
remembered per mode — Ctrl-P/Ctrl-N walk back
through them. Both live in plain TOML under
$XDG_STATE_HOME/pikr/.
Pick a range, launch it
v/V anchors a range over the result list; Enter executes every row in it. Twelve emoji, four apps, a block of dmenu lines — one accept.
modes
Seven sources of selectable rows, one keymap.
Modes implement a single Mode trait:
collect() -> Vec<Entry>, and every entry carries a
payload — print to stdout, spawn detached, or set the clipboard. Picker
state, key dispatch, matcher, and UI are mode-agnostic; execution never goes
back through the mode. Plugin host (WASM / dyn) is tracked as a followup.
Flags for the awkward cases.
keys
The bindings you already know.
Three modes, vim semantics. pikr opens in Insert so you can just start
typing; Esc drops to Normal, i goes back, and
v opens a Visual range over the results. Start in Normal instead
with --mode normal.
install
Native packages on every tagged release — .deb, .rpm, AUR, Homebrew, Scoop.
Every tag ships x86_64 Linux (glibc), Windows MSVC, and macOS (Intel + Apple
Silicon) binaries, plus a Debian .deb and a Fedora/RHEL
.rpm, each with a SHA-256 sidecar. aarch64 Linux and musl are
out for now — the cross-compile plumbing for floem's GTK deps is still being
sorted, and the Alpine .apk is parked behind it. On Linux the
picker is Wayland-only: a compositor advertising
wlr-layer-shell-unstable-v1 is required. macOS binaries build
and install, but the launcher's window behaviour there hasn't been validated
end to end yet.
$ yay -S pikr-bin $ paru -S pikr-bin $ pikr
$ brew install kryptic-sh/tap/pikr $ pikr
# Debian / Ubuntu / Mint / Pop!_OS $ curl -fsSLO https://github.com/kryptic-sh/pikr/releases/latest/download/pikr_*_amd64.deb $ sudo dpkg -i pikr_*_amd64.deb # Fedora / RHEL / Rocky / Alma / openSUSE $ sudo dnf install https://github.com/kryptic-sh/pikr/releases/latest/download/pikr-*.x86_64.rpm
> scoop bucket add kryptic https://github.com/kryptic-sh/scoop-bucket > scoop install kryptic/pikr
$ git clone https://github.com/kryptic-sh/pikr $ cd pikr $ cargo build --release # Linux build deps: libgtk-3-dev + libxkbcommon-dev # binary in target/release/pikr