--- type: research status: analyzed confidence: high created: 2026-10-17 question: What exactly makes ranger great, what makes it slow and fragile, and what must a Rust successor keep or fix? tags: [research, ranger, file-manager] --- # Ranger deep dive ## Research question Ranger is the most feature-complete terminal file manager but famously slow in specific scenarios. We need a precise keep/fix list before writing a single line of viexp. ## Findings ### Project state (Oct 2026) Python + curses, Miller-columns UI. 17.4k stars, ~900 open issues, last tag v1.9.4 (Nov 2024), commits still trickling. Maintainers openly state they lack manpower (issue #1717). ### Architecture - Config = 4 files with **different merge semantics**: `rc.conf` merges, `rifle.conf` replaces, `scope.sh` replaces (~700-line bash), `commands.py` merges (Python subclassing). - Preview pipeline = external `scope.sh`; communicates via exit codes: `0` = stdout preview, `1` = none, `2` = fixed-height text, `5` = image written to cache dir. - Plugins = Python monkeypatching with full interpreter access ("Plugins have full access to your computer!"). Ecosystem: ranger-devicons, ranger-zoxide, ranger-fzf-filter, etc. - Image protocols: w3m, ueberzug, urxvt, kitty, sixel, iterm2, terminology. ### Why it is slow (root causes) | Cause | Evidence | |-------|----------| | Synchronous UI loop — directory listing + `stat` of every file run inline | issue #1173: 100k files = multi-second uninterruptible hang (open since 2018) | | No async I/O anywhere; threading refactor stalled | issue #1025 literally labeled `wants-async` | | `statvfs` on **every status-bar refresh** → 4–10 s j/k lag on sshfs/NFS/CryFS/s3fs | issue #1025; vifm stays fast in identical setups | | Python interpreter startup ~1 s cold | issue #1717 | | Every preview spawns scope.sh + a chain of external binaries | architecture | ### Pain points (user-verified) 1. ueberzug unmaintained and X11-only; ueberzugpp fixes exist but are bolted on (ranger #3188, #3158, #2995; ueberzugpp #122 fractional-scaling bug on Sway/Hyprland). 2. Network mounts unusable without manual `setlocal` hacks or `F` (freeze_files). 3. `:flat` broken past ~30k files (#379). 4. No built-in trash — ArchWiki documents `map DD shell gio trash` as the workaround. 5. Config fragmentation: four files, four formats, four merge behaviors. ### What users love (must keep) Vim keys, Miller columns, `:bulkrename` via `$EDITOR` (the killer feature), rifle-style ordered opener menu (`r`), preview breadth (20+ types), tabs/bookmarks/marks, `:filter`, `--choosefile/--choosedir` + cd-on-exit, per-path options (`setlocal`). ## Keep / Fix table | Keep | Fix | |------|-----| | Miller 3-pane layout, vim key vocabulary | Native binary startup (no interpreter) | | `:bulkrename` via `$EDITOR` | Async dir loading / stat / preview — UI never blocks | | Rifle-style opener rules + chooser menu | No `statvfs` per frame; poll with timeout+backoff | | Exit-code preview contract (scope.sh idea) | First-class trash (`gio trash`-compatible) + undo | | Preview breadth with caching | Native kitty/sixel/ueberzug++ graphics, Wayland-safe | | `setlocal` per-path options | One config format (TOML) with documented merge semantics | | `--choosefile/--choosedir`, cd-on-exit | Virtual scrolling for 100k+ entry dirs | | `F` freeze escape hatch | Automatic freeze on network/fuse mounts | ## Outcome Direct input to [[decisions/ADR-002-extension-architecture|ADR-002]] (extension model), ADR-004 (preview protocols) and the roadmap's async requirements (Sprint 8). ## Sources - https://github.com/ranger/ranger — README, wiki, examples/plugins - https://wiki.archlinux.org/title/Ranger - Issues: #1717 (startup), #1173 (100k files), #1025 (network lag), #379 (`:flat`), #3188 / #3158 / #2995 (ueberzug family) - https://github.com/seebye/ueberzug (unmaintained notice), https://github.com/jstkdng/ueberzugpp - Community: r/commandline "Is yazi overhyped?", r/linux FM threads, x-cmd six-FM comparison, https://mqdir.com/blog/file-management/nnn-vs-yazi