The Terminal Is a Design Tool
I've been building CLI tools for years, and somewhere along the way I realized something: the terminal teaches you more about interface design than any design system ever will.
Not because it's better than a GUI. Because it's more constrained. And constraints are where good design lives.
80 columns of truth
In a GUI, you can always add another panel, another modal, another tooltip. In a terminal, you have roughly 80 columns and whatever fits on one screen. That's it.
This forces you to answer the hardest design question first: what does the user actually need to see right now?
# Bad: showing everything
┌─────────────────────────────────────────────────┐
│ Build #4521 │
│ Status: SUCCESS │
│ Branch: main │
│ Commit: a1b2c3d │
│ Author: david │
│ Duration: 3m 42s │
│ Started: 2026-01-08T14:32:00Z │
│ Finished: 2026-01-08T14:35:42Z │
│ Artifacts: 3 │
│ Coverage: 87.2% │
│ Warnings: 12 │
│ Node: v20.18.0 │
│ OS: linux-x64 │
└─────────────────────────────────────────────────┘
# Good: showing what matters
✓ Build #4521 passed (3m 42s) — main@a1b2c3d
One line. Everything you need. The rest is available if you ask for it (--verbose), but the default is the useful answer, not the complete answer.
Progressive disclosure, but honest
GUIs hide complexity behind menus and settings panels. CLIs hide it behind flags and subcommands. The difference is that CLIs make the hiding explicit.
deploy # sensible defaults
deploy --dry-run # show me what would happen
deploy --region us-west-2 # override one thing
deploy --verbose # show me everything
Each flag is a question the user is asking. If you design your flags well, they read like a conversation:
- "Deploy." → Done.
- "Wait, show me first." → Here's what would happen.
- "Actually, deploy to this region." → OK, deploying to us-west-2.
- "Something went wrong, show me everything." → Here's the full log.
Error messages are the real UI
The moment that matters most in any interface is when something goes wrong. CLIs force you to get this right because you can't fall back on a red banner or a modal with a sad face emoji.
# Bad
Error: ENOENT
# Better
Error: config file not found at ./config.yaml
# Best
Error: config file not found at ./config.yaml
Expected: ./config.yaml
Searched: /Users/david/project, /Users/david, /etc
To create one: run `mytool init`
To use a different path: --config /path/to/file
The best error message tells you three things: what happened, why it happened, and what to do about it. Most GUIs get the first one right. Few get all three.
The lesson for all interfaces
Whether you're building a CLI, a web app, or an API, the terminal's constraints teach the same lessons:
- Default to the useful answer, not the complete one
- Make complexity opt-in, not hidden
- Error states are your most important UI
- If you can't explain it in 80 columns, you don't understand it yet
The terminal didn't teach me to love constraints. It taught me that constraints are where clarity comes from.