- Published on
The Terminal TUI Renaissance — Developers Leaving GUIs and Coming Back to the Terminal
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Introduction — Why the Terminal, Again
- Slumber — Postman in Your Terminal
- The Best TUIs by Category
- fzf — Wherever There Is a List, There Is fzf
- Multiplexers — tmux and zellij
- A Combined Workflow — A Backend Developer Morning
- Build One Yourself — a Taste of ratatui and bubbletea
- Companion Tools Worth Installing Alongside
- Adoption Guide — Gradually, One at a Time
- Limits and a Critical View
- Closing Thoughts
- References
Introduction — Why the Terminal, Again
Recently a terminal-based HTTP client called Slumber was featured on Hacker News and GeekNews to a warm reception. It is a tool that aims to replace Postman from inside the terminal, and the mood in the comments was telling. Not "another TUI?" but "finally, a usable TUI in this category too." It is a continuation of the wave that saw tools like lazygit, k9s, and btop accumulate tens of thousands of GitHub stars.
There are structural reasons TUIs (Text-based User Interfaces) are rising again.
First, remote development became the default. As dev environments moved to cloud VMs, containers, and the far side of SSH, "the same tools everywhere" gained value. Forwarding a GUI is painful; a TUI just needs SSH.
Second, the keyboard workflow is being re-appreciated. A working rhythm where your hands stay on the home row with no mouse round-trips is hard to give up once it sticks. With vim keybindings becoming a de facto standard interface, learning transfers easily between tools.
Third — the new variable of 2026 — the chemistry between AI coding agents and the terminal. In an era when agents like Claude Code live in the terminal, having the rest of your tools inside the same terminal multiplexer eliminates context switching. The scene where an agent fixes code in the left pane while you review diffs in lazygit on the right pane is now ordinary. GUI apps have no seat in this loop.
This post starts with Slumber, then walks through the best TUIs by category, combined workflows, and a taste of building your own with ratatui and bubbletea.
Slumber — Postman in Your Terminal
Slumber is an HTTP client written in Rust, notable for shipping in three forms at once. From a single configuration file, you can use it as a TUI (interactive exploration), a CLI (for scripts and CI), and a library (called from Rust code).
The core concept is the recipe. You define requests declaratively in a YAML file and reuse them. Think of it as the plain-text version of a Postman collection — which means it is naturally version-controlled in git and code-reviewable.
# slumber.yml — auto-detected at the project root
profiles:
local:
data:
host: http://localhost:8000
production:
data:
host: https://api.example.com
requests:
login: !request
method: POST
url: "{{host}}/auth/login"
body: !json { "username": "demo", "password": "hunter2" }
list_users: !request
method: GET
url: "{{host}}/users"
authentication: !bearer "{{chains.auth_token}}"
query:
- page=1
- limit=20
chains:
auth_token:
source: !request
recipe: login
selector: $.token
The chains section above is where Slumber shines. The dependency "extract the token from the login response with JSONPath and put it in the Bearer header of the next request" is handled purely by declaration. Usage looks like this:
# TUI mode — explore interactively, switch profiles, inspect responses
slumber
# CLI mode — run the same recipe from scripts/CI
slumber request --profile production list_users
# Extract just the response and pipe it onward
slumber request login | jq .token
The combination of "declarative request definitions you can share with teammates + instant execution in the terminal" is a genuinely attractive alternative for teams tired of Postman licensing issues and Electron app fatigue.
The Best TUIs by Category
git — lazygit
The poster child of the TUI renaissance. Staging, commits, branches, rebases, and stashes are all handled with shortcuts.
# Install
brew install lazygit # macOS
sudo apt install lazygit # Ubuntu 25.10+
# A common flow: per-file / per-hunk staging
# In the files panel: space = toggle file, enter = drill into hunks
# c to commit, P to push, r on a branch for interactive rebase
Hunk-level staging and interactive rebase are the showstoppers. Replacing the editor-based git rebase -i with arrow keys and shortcuts is an experience that makes plain CLI git hard to return to. It is also perfect for reviewing and squashing the commits an AI agent has piled up.
Kubernetes — k9s
An essential for cluster operators. Navigate between resources at speed without memorizing kubectl commands.
k9s # launch
# :pods → pod list (colon switches resource types)
# /error → filter the list
# l → logs, s → shell into pod, d → describe
# ctrl-d → delete, :ctx → switch context
During an incident, the speed of hopping between "pod list → logs → events → node status" is simply not comparable to typing kubectl or clicking a web dashboard.
Docker — lazydocker
The Docker counterpart by the author of lazygit. Containers, images, volumes, logs, and stats on one screen. It is the shortest path to "which service died and why" in a docker compose environment.
Databases — rainfrog, harlequin
rainfrog is a lightweight PostgreSQL-focused query explorer; harlequin is closer to a "terminal SQL IDE" supporting DuckDB, SQLite, Postgres, and more. Both offer vim keybindings for query editing and result navigation.
harlequin mydata.duckdb # open a DuckDB file
rainfrog --url postgres://user@localhost/mydb
File manager — yazi
A next-generation file manager written in Rust. Async IO keeps it responsive even in giant directories, and it ships image previews (on terminals supporting the kitty graphics protocol), bulk rename, and zoxide integration.
Monitoring — btop
The spiritual successor to htop. CPU, memory, disk, network, and processes in a gorgeous screen that even supports the mouse. GPU monitoring is supported as well.
The Recommendations at a Glance
| Category | Tool | One-liner |
|---|---|---|
| git | lazygit | the definitive hunk staging and rebase |
| Kubernetes | k9s | the standard for cluster navigation |
| Docker | lazydocker | shortest path to compose debugging |
| HTTP | slumber | recipe-based, TUI/CLI/library in one |
| DB | harlequin | a SQL IDE in the terminal |
| Files | yazi | async + previews + bulk operations |
| Monitoring | btop | a beautiful, fast system dashboard |
| Fuzzy finder | fzf | the universal interface for any list |
| Multiplexer | tmux, zellij | the vessel that holds every TUI |
fzf — Wherever There Is a List, There Is fzf
fzf is less a standalone tool and more a building block that "takes any list and turns it into an interactive picker." Learn a handful of recipes and the difference is immediate.
# 1. Fuzzy branch checkout
git branch --all | grep -v HEAD | fzf | sed 's/.* //' | xargs git checkout
# 2. Pick processes to kill
ps -ef | fzf -m | awk '{print $2}' | xargs kill -9
# 3. History search via the default keybinding (ctrl-r)
# Enable shell integration to get ctrl-r/ctrl-t/alt-c
eval "$(fzf --bash)" # bash; use fzf --zsh for zsh
# 4. Code search with ripgrep + preview
rg --line-number --no-heading . | fzf --delimiter : \
--preview 'bat --color=always --highlight-line {2} {1}'
# 5. Fuzzy-pick an SSH target
grep -E '^Host ' ~/.ssh/config | awk '{print $2}' | fzf | xargs -o ssh
The point is not so much "learning fzf" as building the habit of appending fzf to the end of a pipeline.
Multiplexers — tmux and zellij
The vessel that holds all these TUI tools is the multiplexer. Your work survives a dropped SSH session (detach/attach), and split panes let several TUIs run side by side.
tmux is the standard but has a configuration barrier to entry; zellij is the modern alternative with friendly defaults. A hint bar with keybindings is always visible at the bottom, flattening the learning curve.
# tmux essentials only
tmux new -s work # create a session
# prefix(ctrl-b) + % : vertical split, " : horizontal split, d : detach
tmux attach -t work # reattach
# zellij — codify your dev environment as a layout file
zellij --layout dev.kdl
# dev.kdl — example layout that brings up the whole dev environment at once
layout {
pane split_direction="vertical" {
pane command="nvim"
pane split_direction="horizontal" {
pane command="lazygit"
pane command="btop"
}
}
}
A Combined Workflow — A Backend Developer Morning
Tools multiply in value when combined. Here is a fictional but typical scenario.
┌────────────────────────── tmux: work session ───────────────────────┐
│ ┌───────────────┬──────────────────┬───────────────────────────┐ │
│ │ pane 1 │ pane 2 │ pane 3 │ │
│ │ nvim │ AI coding agent │ k9s (staging cluster) │ │
│ │ (code review)│ (bugfix duty) │ + lazygit (commit review)│ │
│ └───────────────┴──────────────────┴───────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
- Arrive at work, run tmux attach once, and return to exactly yesterday's screen.
- Investigate the API 5xx that paged overnight. Open the pod logs in k9s and identify the error pattern.
- To reproduce, bring up the Slumber TUI, hit the failing endpoint with the production profile, then flip the recipe to the local profile to validate a candidate fix.
- Delegate the fix itself to the AI agent, and meanwhile review the agent's accumulating commits hunk by hunk in lazygit.
- For the suspicious query performance, connect to the staging DB with harlequin and inspect the execution plan.
- Before merging, pick the branch with fzf and check it out; while CI runs, watch local load in btop.
Throughout all of this, your hands never leave the keyboard and your screen never leaves one terminal. The crucial part: even on a remote dev machine over SSH, the experience is identical.
Build One Yourself — a Taste of ratatui and bubbletea
The other engine behind the TUI renaissance is the maturing of frameworks. Rust's ratatui and Go's bubbletea are the two pillars.
ratatui (Rust) — Immediate-Mode Rendering
ratatui redraws the UI every frame, immediate-mode style. A mini counter example:
use crossterm::event::{self, Event, KeyCode};
use ratatui::{
widgets::{Block, Borders, Paragraph},
DefaultTerminal,
};
fn main() -> std::io::Result<()> {
let mut terminal = ratatui::init();
let result = run(&mut terminal);
ratatui::restore();
result
}
fn run(terminal: &mut DefaultTerminal) -> std::io::Result<()> {
let mut count = 0i64;
loop {
terminal.draw(|frame| {
let body = Paragraph::new(format!("count: {count} (j/k to change, q to quit)"))
.block(Block::default().title("mini-counter").borders(Borders::ALL));
frame.render_widget(body, frame.area());
})?;
if let Event::Key(key) = event::read()? {
match key.code {
KeyCode::Char('j') => count -= 1,
KeyCode::Char('k') => count += 1,
KeyCode::Char('q') => return Ok(()),
_ => {}
}
}
}
}
bubbletea (Go) — the Elm Architecture
bubbletea follows the Elm architecture: Model (state) → Update (message handling) → View (rendering).
package main
import (
"fmt"
"os"
tea "github.com/charmbracelet/bubbletea"
)
type model struct{ count int }
func (m model) Init() tea.Cmd { return nil }
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if key, ok := msg.(tea.KeyMsg); ok {
switch key.String() {
case "k":
m.count++
case "j":
m.count--
case "q":
return m, tea.Quit
}
}
return m, nil
}
func (m model) View() string {
return fmt.Sprintf("count: %d (j/k to change, q to quit)\n", m.count)
}
func main() {
if _, err := tea.NewProgram(model{}).Run(); err != nil {
os.Exit(1)
}
}
Either framework gets you a working prototype in thirty minutes. The pattern of building "team-only micro tools" — an internal deploy board, an on-call checklist, a log filter — as TUIs and handing out a single binary is becoming increasingly common. It is also a well-shaped task to hand to an AI agent: "wrap this CLI in a bubbletea TUI."
Companion Tools Worth Installing Alongside
Beyond the core tools covered above, here are companions that compound the value when installed together.
| Tool | Area | One-liner |
|---|---|---|
| atuin | shell history | stores history in SQLite, cross-machine sync and powerful search |
| zoxide | directory jumps | a learning replacement for cd, jump to frequent paths |
| bat | file viewing | cat with syntax highlighting, the natural partner of fzf previews |
| dive | docker images | per-layer size and change analysis |
| lnav | logs | format-detecting log navigator with SQL queries |
| dust | disk | a visual du, large directories at a glance |
| glow | markdown | render READMEs beautifully in the terminal |
| posting | HTTP | another TUI HTTP client, built on Textual |
# Install example (Homebrew)
brew install atuin zoxide bat dive lnav dust glow
# atuin: replace ctrl-r with a synced search UI
atuin import auto
eval "$(atuin init zsh)"
# zoxide: z instead of cd — paths you have visited jump with partial input
eval "$(zoxide init zsh)"
z blog # e.g., jumps to ~/projects/my-blog
What these tools share is low adoption risk. They slot into the place of existing commands (cat, cd, du, ctrl-r), pay off immediately, and if you dislike them you simply go back to the original command.
Frequently Asked Questions
Our team is IDE-centric — is this still relevant?
TUIs do not replace IDEs. Even with JetBrains or VSCode, lazygit and fzf deliver their full value inside the built-in terminal panel. In fact, that is the most common combination.
Does this work on Windows?
Inside WSL2, everything works. On native Windows, much of it — lazygit, fzf, btop ports — runs under Windows Terminal, but validate before making it a team standard.
Is it not slow over multi-hop SSH?
TUIs redraw only the changed cells, not the whole screen, so they are surprisingly resilient to latency. In packet-lossy environments, pairing with mosh is an option.
The AI agent does everything — do I still need to learn the tools?
Verifying the agent's output remains a human job. Reviewing diffs (lazygit), checking cluster state (k9s), and reproducing requests (slumber) are the core tools that make that verification loop fast.
There are too many tools — I fear configuration hell.
The tools in this post deliberately aim for zero configuration. lazygit, k9s, and btop are perfectly usable with defaults right after install. Touch the config files only after you actually feel the friction.
Adoption Guide — Gradually, One at a Time
I have seen many attempts fail by switching everything at once. The order I recommend:
- Week 1: fzf. Enabling just the shell integration (ctrl-r history search) pays off instantly. Zero risk.
- Week 2: lazygit. Your existing git knowledge transfers directly, so the learning cost is low and the payoff is the largest.
- Week 3: tmux or zellij. Use only splits and detach/attach at first. Defer the temptation of config tuning.
- Week 4 onward: domain tools. Add k9s if you touch Kubernetes, slumber if you build APIs, harlequin if you work with databases.
- Always: keep the escape hatch. The moment a TUI gets in the way, fall back to the original CLI/GUI without hesitation. Tools are not a religion.
For team adoption, share configs in a dotfiles repository — and one lunchtime demo beats ten pages of documentation.
Limits and a Critical View
For balance, the weaknesses of TUIs deserve clear-eyed treatment.
- The learning curve is real. Shortcut-driven interfaces come with a productivity dip in the first week or two. Avoid adopting them right before a deadline.
- Accessibility is a serious problem. Screen readers can traverse a GUI accessibility tree, but a TUI's cell-based screen struggles to convey semantic structure. If a teammate is visually impaired, mandating TUI-only workflows can be an exclusionary decision.
- Discoverability is low. A GUI lets you discover features by browsing menus; a TUI requires actively opening the help (usually the question-mark key).
- Terminal compatibility issues. True color, image previews, and mouse support vary across terminal emulators. Teams with mixed Windows environments need up-front validation.
- Not all work is text. Design review, complex graph exploration, and shared dashboards remain better served by GUIs and the web.
The accurate conclusion is not the slogan "back to the terminal," but "for work whose essence is text and keyboard, use tools shaped for it."
Closing Thoughts
The TUI renaissance is not a retro hobby. It is the result of three currents converging — remote development becoming universal, the keyboard-centric workflow being re-appreciated, and AI agents that live in the terminal — making the terminal once again the center of gravity of development work. New tools like Slumber keep appearing and the ratatui/bubbletea ecosystems keep growing; that is evidence this is no passing fad.
If you start with just one thing today, enable fzf's ctrl-r. Open lazygit next week. A month from now, your tmux session will hold more than you expected.
References
- Slumber (GitHub): https://github.com/LucasPickering/slumber
- Slumber official docs: https://slumber.lucaspickering.me/
- GeekNews — Slumber feature: https://news.hada.io/topic?id=30337
- Hacker News: https://news.ycombinator.com/
- lazygit (GitHub): https://github.com/jesseduffield/lazygit
- k9s official site: https://k9scli.io/
- lazydocker (GitHub): https://github.com/jesseduffield/lazydocker
- yazi (GitHub): https://github.com/sxyazi/yazi
- btop (GitHub): https://github.com/aristocratos/btop
- fzf (GitHub): https://github.com/junegunn/fzf
- harlequin official site: https://harlequin.sh/
- rainfrog (GitHub): https://github.com/achristmascarl/rainfrog
- zellij official site: https://zellij.dev/
- ratatui official site: https://ratatui.rs/
- bubbletea (GitHub): https://github.com/charmbracelet/bubbletea