Files
viexp/docs/research/competitor-landscape.md
T

77 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: research
status: analyzed
confidence: high
created: 2026-10-17
question: Which terminal file managers exist in 2026, what does each do best, and which ideas should viexp adopt or avoid?
tags: [research, file-manager, yazi, nnn, lf, vifm, broot]
---
# Competitor landscape (October 2026)
## Feature matrix
| Manager | Lang | TUI | Image preview | Extensions | Config | Async | State (last release) |
|---|---|---|---|---|---|---|---|
| **yazi** | Rust | ratatui | native kitty/iterm2/sixel/ueberzug++/chafa | Lua (mlua, vendored) + `ya pack` | TOML ×3 | tokio, fully | Very active, v26.9.1 (2026-09) |
| **nnn** | C | ncurses | via FIFO plugins | any executable; `NNN_PIPE`/`NNN_FIFO` protocol | none (flags+env) | no (tiny by design) | Active, v5.3 (2026-08) |
| **lf** | Go | own | sixel native; else scripts | shell cmds, `push`, remote socket API | lfrc DSL | async I/O | Active, r42 (2026-07) |
| **joshuto** | Rust | tui-rs/termion | external scripts | config only | 5 TOMLs | partial | Semi-stalled, v0.9.9 (2025-05) |
| **felix** | Rust | termion | chafa + bat | none | YAML | partial | Dormant since 2025-04 |
| **hunter** | Rust | own | halfblock/sixel/kitty | mime actions | conf+keymap | heavily threaded | Dead (2020/2022) |
| **vifm** | C | ncurses | community scripts only | vim-like `:commands` + Lua | vifmrc | no | Active, v0.14.4 (2026-05) |
| **broot** | Rust | crossterm+termimad | kitty graphics | verbs, skins | TOML | interruptible search | Very active, v1.61 (2026-10) |
| **mc** | C | own | none | extfs VFS helpers | menus | background ops | Active, 4.8.33 |
## What the winners do right
- **yazi** (~43k stars): ~25-crate workspace, everything on tokio; micro/macro worker pools with
priorities (mime/previews preempt copying); **paged preloading** — only visible rows get work;
three cancellation mechanisms (tokio abort, atomic tickets for CPU work, instruction-count
checks for Lua); two-pass image pipeline (downscale+cache → fit to terminal); DDS pub/sub
between instances without a daemon. v25.4 doubled startup speed via config parser rewrite.
- **nnn**: 150 KiB binary, zero config; plugins = executables with env-var contract
(`$1` hovered file, `$2` cwd, `$3` picker) and a tiny write-back protocol via `NNN_PIPE`;
`NNN_FIFO` streams hovered paths so external scripts render live previews.
- **lf**: external `previewer(file, w, h, x, y)` + `cleaner` contract with exit-code-controlled
caching; `push` simulates keystrokes making mappings composable; server model over Unix socket.
- **broot**: every keystroke interrupts the running search; fuzzy+regex+content combined with
boolean operators; collapsed tree respecting .gitignore.
- **felix**: built-in trash + undo/redo + zoxide `z` jump — small features with huge daily value.
## Ideas worth stealing (ranked)
1. yazi's paged task scheduling + prioritized workers + cancellation tickets (perceived speed)
2. Protocol auto-detection adapter layer behind one trait (kitty/iterm2/sixel/ueberzug++/chafa)
3. lf's previewer/cleaner argv contract — cheapest path to infinite formats
4. nnn's FIFO hover event stream for external live previews
5. yazi's TOML tables with `prepend_*`/`append_*` merge semantics for rules
6. TOML for config + (later) Lua for behavior + pinned plugin packages
7. broot's interruptible, composable search
8. lf's `push` key-simulation primitive
9. felix's trash + undo + `z` jump
10. Performance as a marketable feature (both nnn and yazi publish benchmarks)
## Anti-patterns to avoid
| Trap | Victim | Lesson |
|------|--------|--------|
| Full ranger parity alone | joshuto | 5 config files, janky command line, 14-month release gap → audience left for yazi. Ship narrow and polished. |
| Nightly compiler + heavy C deps | hunter | GStreamer + nightly = unbuildable for users. Stable Rust, spawned binaries for media. |
| No native graphics path | vifm, nnn, mc | Preview zoo of mutually incompatible scripts. Build the adapter layer early. |
| Bespoke config DSL | lf | A whole parser users must learn; standard TOML + scripting runtime beats it. |
| Doctrinal non-features | lf (no tabs) | Minimal defaults and power features are not contradictory (yazi proves it). |
| Monolith | mc | Thin core + clean contracts. |
| API churn without pinning | yazi (mild) | Plugin version pinning story from day one. |
| Silence without governance | felix, hunter | Release cadence = perceived life. |
## Outcome
Shaped ADR-001 (ratatui), ADR-002 (extension phases), ADR-004 (protocol chain), and the
roadmap order (core narrow first, previews second, plugins third, Lua last).
## Sources
- yazi: github.com/sxyazi/yazi, https://yazi-rs.github.io/blog/why-is-yazi-fast/, releases v25–v26
- nnn: github.com/jarun/nnn + plugins/README.md
- lf: github.com/gokcehan/lf + doc.md
- joshuto, felix, hunter, vifm, broot, mc: repos + release APIs (dates verified 2026-10-17)