I opened a budget app last month to check one number, how much I had left to spend, and I could not find it. The balance was on one screen, the spending was on another, and the budget was a third screen with a tiny progress bar I had to squint at. I knew the data was in there somewhere, the app had it, it just was not showing me. I closed it and did the math in my head instead, which is the exact moment a UI has failed at its job.
I keep coming back to a line from Ben Halpern's post, ask more of your UI. The idea is simple: a UI should act like an instrument panel, showing you what is going on, live, instead of hiding the state behind taps and menus. A car dashboard does not make you open a menu to see your speed. It is just there, all the time, because the whole point of the dashboard is to tell you where you stand.
I built a little budget tracker to try the idea out, nothing fancy, just a panel that shows the four things I actually check. Balance, spent this month against the budget, the next bill coming up, and whether the data is synced. Every number updates the moment something changes, so the panel is always current. Here is the version the demo below runs, with buttons to add an expense and watch the numbers move.
Try it: a budget panel that talks back
Try it live on nayemalam.com.
the quiet UI vs the panel
The quiet version of this app is the one I opened last month. It has the same data, but it shows you almost none of it. You tap through three screens to assemble the picture yourself, and by the time you have, you have forgotten why you opened the app. The panel version puts the four numbers on one screen and keeps them current. Nothing about it is clever, and that is the point. The clever part would be hiding the numbers behind a gesture.
The pattern shows up everywhere once you start looking for it. A form that tells you the password is too short while you type, instead of after you submit. A file upload that shows progress and a real error message, instead of a spinner that just keeps spinning. A settings page that says when it last synced, instead of leaving you to wonder whether your change saved. In every case, the fix is the same: surface the state, keep it live, and let the user see it without asking.
the cost is real, and small
The objection I hear is that showing more state means more code, and more code means more bugs. That is fair, and it is also mostly wrong at this scale. The budget panel is a handful of useState calls and a progress bar. The state already exists in the app, it is the same state the quiet version hides. The work is not computing the numbers, it is deciding to render them. The extra code is a few lines of JSX, and the payoff is that the user stops doing mental math to fill in the blanks.
Where I draw the line is noise. An instrument panel is not a firehose. A car dashboard shows speed, fuel, and warnings, not the raw sensor feed. The budget panel shows four numbers, not every transaction since 2019. The test I use is whether the number changes a decision. Balance changes whether I buy something. Spent-against-budget changes whether I cook tonight. Sync status changes whether I trust the numbers at all. If a number would not change a decision, it does not earn a spot on the panel.
What I took away from building the panel is that showing state is a design choice, not a feature. The data was always there. The quiet app had it and hid it. The panel just decided the user is allowed to see it. I check the budget app more now, not because I enjoy budgeting, but because opening it answers the question in one glance instead of three taps. A UI exists to tell you what is going on, and the ones that do it well feel less like software and more like a dashboard you can trust.
Originally posted on nayemalam.com/blog.
