
#Why the terminal deserves the same care we give to every other interface
I’ll never forget watching a senior engineer completely lose it over a CLI tool. Not because it failed. But because it gave them an error message that said: “Error: invalid input.”
That was it. No context. No suggestion. No path forward. Just three words that sent them down a two-hour debugging rabbit hole that could have been avoided with one good sentence.
We talk endlessly about pixel-perfect interfaces and delightful micro-interactions in our apps. We obsess over button colors and navigation patterns. But when it comes to the command line, where developers spend most of their actual working hours, we accept that “good enough” is fine.
Here’s my thesis: Design isn’t just living in your Figma files and React components. Design is living in the terminal, in error messages, in the flow of commands, in every interaction a developer has with their tools.
#The invisible interface problem
The command line has an invisibility problem. Because it doesn’t have buttons or gradients or smooth animations, we don’t think of it as designed. We think of it as technical. Purely functional. Something that exists outside the realm of user experience.
But think about what happens when a developer runs a deployment command. They’re anxious. They’re hoping nothing breaks. They’re watching the output scroll by, looking for any sign that something went wrong. That moment is pure user experience. The feedback they get, the clarity of the messages, the confidence they feel. That’s all design.
I learned this while solving developer experience problems. I was working on CLI tools for managing infrastructure, and despite solid engineering, developers struggled with them. Why? Because we treated it like a technical problem instead of a design problem. We wrote error messages that made sense to us. We created command structures that matched our internal mental models. We assumed developers would just “figure it out.”
Smart people still deserve good design. Their time is valuable and their problems are complex enough without their tools making things harder.
#Three principles that changed everything
After spending time solving developer experience challenges, conducting user interviews, and rebuilding approaches from the ground up, I’ve learned that great command-line design comes down to three core principles.
#1. Empathy lives in error messages
Every error message is a moment where your relationship with the developer either strengthens or fractures. When something goes wrong, you have a choice. You can be cryptic and technical, or you can be helpful and human.
Authentication failed (401)Authentication failed. Your API key expired on Nov 15.Run 'platform login' to generate a new one.The difference isn’t just the words. It’s the empathy. The good message understands what the developer needs in that moment. They don’t need to know the HTTP status code. They need to know what went wrong and exactly how to fix it.
I started thinking of error messages as conversations. If a colleague came to me with a problem, I wouldn’t say “Error 401” and walk away. I’d explain what happened and tell them the next step. Why should our tools be any less helpful?
#2. Complexity should be optional, not mandatory
Here’s a trap I see constantly: developers who built the tool know every flag, every option, every edge case. So they expose everything upfront. The result? Commands that look like this:
deploy --env production --region us-west-2 --instance-type t2.micro \ --auto-scaling true --min-instances 2 --max-instances 10 \ --health-check-path /statusNobody wants to type that every time. And more importantly, nobody can remember it.
Progressive disclosure applies perfectly to CLIs. Start simple. Make the default behavior cover 80% of use cases. Then let people discover advanced features only when they need them.
deployThat’s it for the basic case. The tool uses smart defaults. But when you need more control:
deploy --advancedOr better yet, make the tool interactive when complexity is needed. Guide people through the options instead of expecting them to memorize flags.
I learned this by watching how developers actually used the tools I was designing. The ones who loved the CLI could accomplish simple tasks simply. The ones who struggled were forced to wade through documentation just to do basic operations.
Apple understands this perfectly. Their products are simple on the surface, powerful underneath. Your CLI should work the same way.
#3. Visual hierarchy isn’t just for screens
One of the most surprising discoveries I made was how much typography and visual design matter in the terminal. We’re working with monospaced text, but that doesn’t mean everything has to be an undifferentiated wall of characters.
Color conveys meaning instantly. Green for success. Red for errors. Yellow for warnings. Blue for informational messages. This isn’t decoration. It’s functional design that helps developers scan output and find what matters.
Spacing creates structure. A wall of text is exhausting to read. Add blank lines between sections. Group related information together. Make important things stand out.
Typography matters more than you’d think. I fell in love with mono fonts while working on CLI tools. The right font makes code easier to scan, errors easier to spot, and output easier to understand. I spent weeks testing different monospace typefaces, and I even started designing my own.
When I pitched these ideas to engineering teams, I compared the CLI to road traffic control systems. When you’re working on mission-critical infrastructure, one wrong deployment can cause massive outages. Visual hierarchy isn’t a nice-to-have. It’s a safety feature. Clear output prevents mistakes. Good visual design helps developers spot problems before they become disasters.
#What to look for in CLI design
Think of CLI design like road traffic control systems. When you’re driving, every sign, every signal, every road marking exists to keep you informed and safe. You see warnings before sharp turns. Stop signs are universally red and octagonal. Highway exits give you advance notice so you can prepare.
The same principles apply to command-line interfaces. Developers need to be informed at every critical decision point because the stakes are real. A single command can delete an entire production database. One mistyped flag can bring down a service that thousands of people depend on.
Here’s what good CLI design needs:
Clear warnings before destructive actions. If a command can delete data, wipe a database, or terminate running services, the developer needs to know before they press enter. Not with a tiny note in the documentation. Right there, in the terminal, with unmistakable clarity.
Confirmation patterns for high-stakes operations. Just like how road construction zones use multiple signs to slow you down and prepare you, CLIs need layered confirmations for dangerous operations. A simple “Are you sure? (y/n)” isn’t enough. Show what will be affected. Require explicit confirmation. Make it impossible to accidentally destroy something critical.
Dry-run modes. Before executing permanent changes, let developers see what would happen. It’s like those “Next exit: 2 miles” signs on highways. Give people the information they need to decide if they’re on the right path before they’ve gone too far.
Status visibility at every step. When a long-running process is happening, developers need to know what’s going on. Not just a spinner that says “loading” but actual progress. What step are we on? What’s happening right now? How much longer? When someone is deploying to production at 2am, knowing what’s happening reduces anxiety and helps them catch problems early.
Exit routes and recovery paths. Traffic systems have emergency lanes and detour signs. Your CLI needs the same. When something goes wrong, show people how to recover. When they want to cancel an operation, make it obvious how to do that safely.
Adding delight. CLIs are content-heavy and that’s the best part. I love Claude Code’s loader phrases that appear during processing. “✨ Purring…”, “Frolicking”, “Gerunding”, “Thinking harder”, “Ultrathink”, “Pleading”. Makes the entire developer experience fun.
The road traffic analogy isn’t just cute. It’s fundamental. Both systems guide people through complex, high-stakes decisions where mistakes have real consequences. The difference is we’ve spent decades perfecting road signs and signals, but we’re still treating CLI design like an afterthought.
#The moment it clicked
There was a specific moment when I knew the design was right. I was watching a developer during a user testing session. They were deploying a major update to their production environment. High stakes. Everyone watching.
They ran the CLI command. The output was clear. The progress indicators showed exactly what was happening. When a warning appeared (a non-breaking issue with one service), they understood it immediately because of how the message and its visual treatment were designed.
The deployment succeeded. But what struck me was what they said afterward: “I actually felt confident the whole time. I knew what was happening at every step.”
That’s the bar. Not “it worked” but “I felt confident.” That’s design.
#Tools that get it right
I’ve been using Ghostty lately, and honestly, it’s changed how I think about terminal emulators. The typography is clean and my favorite theme is Catppuccin. The keyboard shortcuts make sense. It just works the way you’d expect it to. It’s a reminder that even the most technical tools can be well-designed.
Claude Code is another one that gets it. Clear feedback when you’re working through problems. Strong visual indicators of the AI’s current thought process and the permissions it has. It doesn’t make you hunt through docs to figure out what went wrong.
I’ve also fallen in love with TUI tools built with Charm libraries like Bubble Tea. Interactive prompts, progress bars that actually tell you what’s happening, tables you can navigate. The terminal doesn’t have to be boring.
K9s is also amazing, though complicated for a designer’s usage.
These tools exist because someone decided the terminal experience matters. And they’re right.
#Design is living everywhere
The terminal isn’t going anywhere. It’s too powerful, too efficient, too essential to how technical work gets done. Millions of developers use command-line tools every single day, and they’ll continue adding more agentic tools to build amazing software products.
The command line isn’t special. It’s just another interface. And every interface deserves the same level of care we give to our most visible work. Developers are users. Infrastructure engineers are users. DevOps teams are users. The fact that they’re technical doesn’t mean they don’t deserve thoughtful, well-designed experiences.
When we bring the same design thinking to CLIs that we bring to every other interface, something magical happens. Developers spend less time fighting their tools and more time building. Onboarding becomes faster. Debugging becomes easier. Confidence increases. Mistakes decrease.
The next time you’re building a CLI, don’t think of yourself as just writing commands. Think of yourself as designing an experience. Ask the same questions you’d ask about any interface: What does the user need in this moment? How can I make this clearer? What would reduce friction? How can I prevent mistakes?
Your users will thank you for it. I promise.