Stop Arguing About State Management and Look at the User
While engineering teams debate Redux vs. Zustand, users churn because the checkout button took three seconds. Look at the user.
Your users don’t care about your architecture. They care that the checkout button took three seconds to load.
Two Weeks on a Library Nobody Will Notice
Engineering teams are remarkably good at spending time on things that don’t matter. Not maliciously. Not even lazily. Just structurally. Slack threads breed sub-threads. Architecture decisions spawn adjacent architecture decisions. Before long, you’ve spent two weeks debating the right state management library for a CRUD app that hasn’t shipped yet.
Meanwhile, the modal that appears on signup — the one where users need to invite their team — has three ambiguous buttons, no explanation of what “workspace” means, and sends an email that lands in spam. Four out of five users who reach it don’t complete the flow. Nobody has a Slack thread about that.
This is the engineer’s version of rearranging the deck chairs. The difference is that engineers feel productive while doing it. Library debates involve reading docs, writing proofs of concept, comparing bundle sizes. It looks like work. It is work. It’s just not the work that would make a dent in the metric that determines whether the company survives.
The user on the other side of the screen doesn’t know what Redux is. They don’t know what React is. They know the checkout button loaded slowly, that the confirmation email arrived two days after their purchase, that they couldn’t figure out how to change their billing address without contacting support. That’s the product they actually experience. Not the architecture.
Ship Ugly, Fix Later
There’s a persistent fantasy in software teams: the idea that if you build the foundation right, everything else will follow. Get the architecture clean, nail the data model, pick the framework you can live with, and then users will reward your discipline. It’s a seductive story. It’s also backwards.
Users don’t reward architectural discipline. They reward being able to do the thing they came to do. A Rails monolith that loads in 300ms beats a microservices architecture that loads in two seconds. Postgres and a simple ORM will carry you further than you think — further, probably, than your current user count will ever stress-test. The engineer who insists on a distributed event-driven system for an app with 400 active users isn’t building for reality. They’re building for an imaginary future that may never arrive, while the real present — onboarding drop-off, task completion rates, support volume — sits unexamined.
Shipping is the thing. Not because quality doesn’t matter, but because you can’t improve a product that doesn’t exist in the world. Every week you spend in architecture debate is a week you don’t have user data. You don’t know what breaks in production. You don’t know which flow frustrates people. You can’t optimize what you haven’t shipped.
The “boring tech” crowd has this right: Rails and Postgres aren’t compromises. They’re deliberate bets on the thing that actually matters — time to the user. Pick the tools your team knows, ship the thing, and then respond to what the real world tells you. The priority ordering is the discipline.
Three Weeks of Debate, Filters That Die on Refresh
A team builds a complex filter interface — industry, date range, region, price tier. They spend three weeks debating whether to use Zustand or Redux Toolkit. They evaluate middleware patterns. They write custom selectors. They benchmark re-renders.
At the end of three weeks, the filters don’t survive a page refresh. You can’t share a filtered view with a teammate. Bookmarking doesn’t work. The browser’s back button clears everything. Every one of these problems is solved by a single insight: put the filters in the URL. That’s it. Query strings. Technology that’s been in browsers since 1993.
The URL is state. The browser’s history API is a state machine. localStorage has been around for fifteen years. For most of the state problems in most applications, these primitives are sufficient. Not glamorous, but sufficient — and shareable, bookmarkable, cacheable by default.
The obsession with state management libraries isn’t about solving user problems. It’s about solving engineer problems: the desire for pattern consistency, the satisfaction of a well-typed store, the pleasure of a clean abstraction. Those things have value inside an engineering organization. They have zero value to the user who emailed support asking why their filters disappeared when they hit back. Reach for the complex tool when the simple tool fails. Most of the time, the simple tool doesn’t fail.
Empathy as a Technical Skill
UX is not something that happens in another team’s Figma file. It happens in your code. It happens in the empty state you return when a user’s search matches nothing. In the error message you write when the upload fails. In whether the loading spinner appears fast enough that users don’t think the button is broken. In what happens when someone’s session expires mid-form.
These are engineering problems. And most of them don’t get thought about.
The discipline of walking the unhappy paths — deliberately triggering every error state, testing the five-second network delay, submitting the form twice, trying to log in with an account that was deactivated — this is where products separate. The happy path works in almost every codebase. A user entering valid data, following the expected sequence, on a fast connection. That’s the easy case. Build it and it mostly works.
What breaks is everything else. A user who uploads a file that’s 1MB over the limit and gets a raw 413 response. A user who hits the back button after payment and doesn’t know if they were charged. A user who closes a tab mid-onboarding and comes back three days later to a session that’s expired, with no memory of where they were in the flow. These aren’t edge cases. They’re the normal behavior of real people using software in the real world.
If a feature is technically complete but confusing to use, it’s broken. Not in a linting sense. In the sense that matters: users can’t do what they came to do. Engineering owns that outcome just as much as design does.
Every Support Ticket Is a Measurement
Friction isn’t a UX problem. It’s a revenue problem. Every support ticket represents a user who couldn’t figure something out on their own. Every refund request is a user whose expectation wasn’t met. Every churned account is a user who stopped believing the product was worth the effort. These aren’t soft metrics — they’re the signal that tells you whether the product actually works for the people it’s supposed to serve.
The economics here are straightforward. Reducing friction at the top of a funnel compounds downstream. A signup flow that converts one percentage point better doesn’t just mean more signups — it means more trials, more upgrades, more retained accounts, less support load. The user experience is the revenue model walking around in the world.
AI is accelerating this calculus. Boilerplate code — authentication flows, CRUD scaffolding, state management setup — is increasingly generated, not written. The argument for spending three days on your Redux store architecture weakens when an AI writes a working implementation in ten minutes. The thing AI can’t do is sit with a confused user and understand why they clicked the wrong button, why the confirmation message didn’t feel like confirmation, why they gave up on the second screen and never came back.
That’s the work that stays human. Not because it requires creativity in a mystical sense, but because it requires attention to the texture of other people’s experiences. It requires caring that the error message is legible. That the loading state doesn’t look broken. That the flow makes sense to someone who didn’t build it. As code becomes cheaper to generate, the differential value is in the judgment that determines what to build and how it should feel to use. The engineer who develops that judgment builds things worth using. The one who’s still debating state management libraries builds things that work technically and fail in practice.