Skip to content

CLI-First

Why some developers route their entire workflow through the terminal — and how to get there without burning out.

Composability. GUI tools are closed boxes. CLI tools connect with |. A file manager, a fuzzy finder, and a text editor become a single workflow when they share stdin/stdout. See CLI Pipelines.

Speed. Keystrokes are faster than mouse travel. Not marginally — the difference compounds across hundreds of daily actions. A keyboard-driven developer doesn’t context-switch between pointing and typing.

Reproducibility. A shell command is a record of what happened. A sequence of clicks is not. Dotfiles turn your entire environment into a version-controlled, portable artifact.

Remote-friendliness. SSH gives you your full environment on any machine. GUI tools stay on the machine with the display. tmux makes that session persistent.

Focus. A terminal is a text interface. No notification badges, no sidebars, no distracting chrome. The tool you’re using fills the screen.

Four tools compose into a full working environment:

LayerToolRole
TerminalGhostty / iTerm2GPU rendering, splits, native UI
MultiplexertmuxSession persistence, remote splits
EditorNeovimCode editing, LSP, integrated terminal
Fuzzy finderfzfInteractive selection for any list

Everything else builds on top of these four.

The question isn’t “can CLI do X?” — it’s “what do people actually use?”

Instead ofUseWhy
FinderyaziAsync I/O, image previews, tabs, Lua extensible
Spotlightfzf / zoxidefzf for files, zoxide for frecent dirs
Directory navzoxidez project jumps to ~/dev/project
Terminal window
brew install yazi fzf zoxide
Instead ofUseWhy
GitKraken, etclazygitFull TUI: stage hunks, rebase, resolve
git log viewertigncurses browser for log, diff, blame
GitHub UIghPRs, issues, releases from the terminal
Terminal window
brew install lazygit tig gh

See Git Cheatsheet for the underlying commands.

Instead ofUseWhy
Docker DesktoplazydockerContainer/image TUI
Kubernetes Dashboardk9sCluster management TUI
DB GUI (TablePlus)psql / cliDirect SQL, scriptable
REST client (Postman)curl / httpieScriptable, version-controllable
Terminal window
brew install lazydocker k9s httpie

Rust rewrites of Unix classics — faster, friendlier defaults, respects .gitignore.

ClassicReplacementImprovement
grepripgrep10-100x faster, ignores binary/gitignore
findfdIntuitive syntax, colored output
catbatSyntax highlighting, line numbers, git
lsezaIcons, tree view, git status column
cdzoxideFrecency-ranked directory jumping
diffdeltaSyntax-highlighted git diffs
Terminal window
brew install ripgrep fd bat eza zoxide git-delta
Instead ofUseWhy
NotionNeovim + markdownPlain text, version-controlled
PDF viewerless / glowMarkdown rendering in terminal
SpreadsheetsvisidataTabular data viewer/editor, any format
Terminal window
brew install glow visidata
Instead ofUseWhy
Activity MonitorbtopBeautiful, detailed, keyboard-nav
System PrefsdefaultsScriptable macOS configuration
Terminal window
brew install btop

A CLI-first workflow needs keyboard-driven window placement. On macOS:

AeroSpace (recommended) — i3-like tiling. No SIP disable required.

Terminal window
brew install --cask nikitabobko/tap/aerospace

Core concepts:

  • Workspaces: Alt+1 through Alt+9
  • Move window to workspace: Alt+Shift+1 through Alt+Shift+9
  • Split direction: Alt+/ (toggle horizontal/vertical)
  • Focus: Alt+h/j/k/l
  • Move: Alt+Shift+h/j/k/l

The keybindings mirror vim and tmux navigation — h/j/k/l everywhere.

Alternatives:

  • yabai — More powerful, but requires SIP disable for full features
  • Amethyst — Simpler, fewer features, no config file needed

Honesty matters. Don’t force these into a terminal:

  • Image/video editing. GIMP and FFmpeg exist but nobody prefers them for creative work.
  • Web browsing. w3m and lynx are novelties, not workflows.
  • Spreadsheets with formulas. visidata views data well but isn’t Excel.
  • Presentations. Slides need visual layout tools.
  • Video calls. Obviously.

The CLI-first mindset isn’t “never use a GUI.” It’s “default to the terminal and reach for a GUI only when the terminal genuinely can’t do it.”

Going cold turkey fails. Transition gradually:

Pick the GUI tool you use most for something the terminal does well. Usually git. Install lazygit. Use it for all git operations for two weeks.

Install fzf and zoxide. Stop clicking through Finder to find files. Use Ctrl+T (fzf) and z dirname (zoxide) instead.

Install AeroSpace. Learn Alt+h/j/k/l for focus and Alt+Shift+number for workspaces. Stop dragging windows.

Replace remaining GUI tools one at a time. Each replacement takes a few days of friction, then becomes faster than what it replaced.

You’ll know the transition is working when you SSH into a remote machine and feel at home. Your muscle memory works everywhere because it’s all the same tools.

A CLI-first workflow lives or dies by its dotfiles. Version control them.

~/.config/
├── aerospace/ # window manager
│ └── aerospace.toml
├── ghostty/ # terminal
│ └── config
├── nvim/ # editor
│ └── init.lua
├── tmux/ # multiplexer
│ └── tmux.conf
├── bat/ # cat replacement
│ └── config
└── git/ # git
└── config
Terminal window
# Symlink from a git repo
git init ~/dotfiles
# Move configs there, symlink back
ln -s ~/dotfiles/ghostty ~/.config/ghostty

New machine setup becomes: clone the repo, run the symlink script, install packages. Ten minutes to a full environment.