About Author
A formerly masked, now weaponized ASD-1 nihilist with an well-honed hatred for bullshit, who architects software systems just enough to fund a life spent exposing nepo-babies, working on taxing billionaires into extinction, and teaching everyone with a paycheck that their soul isn't a subscription.
On the years spent in the one part of the stack where the difficulty is real and the credit is optional.
I. A joke, not funny
Hand a backend engineer a CSS bug.
Not a cruel one. Nothing exotic. A flex container that refuses, for reasons that will eventually turn out to be both completely documented and completely insane, to respect the height of its own child. Give it to someone whose ordinary working day involves reasoning about distributed consensus, about what happens to a write when a node disappears mid-transaction, about failure modes with names like split brain—a phrase, let’s be honest, that no serious profession should have been allowed to keep.
Come back in an hour.
What you will find is not a person who has solved a small problem. What you will find is a person undergoing something closer to a crisis of faith: a genuinely first-rate mind that has spent sixty minutes discovering that the layout engine is not a system so much as an accumulated series of historical apologies, and that there is no elegant model underneath it, and that the fix—when it arrives—will arrive not through reasoning but through a kind of exhausted supplication.1
Now run it the other way. Hand a frontend engineer a race condition four services deep in a REST call chain. What you’ll typically get is a shrug, a joke about distributed systems being astrology for people with better monitors, and a return, roughly ninety minutes later, with a fix and no visible spiritual damage.
I’ve watched both experiments run, informally, across most of my career and three sizes of companies, and I want to be careful about what I’m claiming, because there’s a cheap version of this observation and it isn’t the one I mean. The cheap version is frontend is actually harder, actually, which is tribal and boring and false in the specific way that all tribal claims are false. The version I mean is narrower and, I think, more damning:
Both problems are hard. Only one of them is permitted to be hard.
One of these difficulties reads, culturally, as engineering—as rigor, as depth, as the sort of thing a promotion committee can picture. The other reads as fiddly. As detail work. As something you’d hope to be finished with rather than something you’d hope to be good at. And that asymmetry—invisible, un-legislated, absolutely never written down anywhere you could point at during a performance review—has been the single largest structural fact of my career.
I’ve started calling it the interface tax. You pay it in career capital, annually, and there’s no form to file.
II. Where I’m standing when I say this
I should be specific about my own position, partly for credibility and partly because the specifics are funnier than the summary.
I started writing software at nine years old, in FoxPro, on Windows 3.1. I want to sit in that for a second, because when people hear “started young” they picture something precocious and cinematic, and what actually happened was a child building database forms on an operating system that would go on to become a punchline, developing a set of instincts about how a person moves through an application before he had any of the vocabulary to describe what he was doing.
Everything after that was new drapes and new shrubs, same house. VB. C#. .NET. PHP. ActionScript, which I will defend until I die, and which I mourn with the specific grief you reserve for a thing that was silly but yours. And now Typescript—which I use, and I need this understood precisely, not because I lack the vocabulary for anything underneath it. I’ve built design systems. I’ve built complex clinical interfaces for medical applications where the cost of a confusing affordance is not a bad quarter but a bad outcome for a person in a bed. I’ve shipped GraphQL APIs, REST APIs, RPC and WebSocket layers when the shape of the problem asked for them. I have watched this industry’s entire center of gravity migrate from compiled on-prem binaries to cloud-native distributed everything, and I didn’t watch it from the stands. Fuck, I built the prem when HP was still HP and 3COM was a standalone brand. Somewhere back in those halcyon days when a front-side bus was a unit of measure.
I build with Typescript because I like the seam.
I like the place where the abstraction stops and a person begins. I like that the interface is the only part of the system that has to survive contact with someone who did not read the documentation, is having a bad day, is holding a phone at a strange angle in bad light, and who will decide—in something under four hundred milliseconds, on grounds they could not articulate under oath—whether this software is trustworthy.2 Everything underneath the interface gets to be correct. Only the interface has to be correct and legible and forgiving and fast and honest about what it’s doing. That’s not a lesser problem. It’s a problem with more constraints and a harsher grader.
The industry’s official position on this, delivered warmly and with real affection, is: cute, but not real engineering.
III. The ladder is decorative
Here is how that position expresses itself structurally, which is the only way positions ever really express themselves.
The individual-contributor ladder, for someone who does what I prefer to do, terminates at Staff. It will walk you all the way up there with an arm around your shoulder—it’s a genuinely respectable place to arrive—and then it will gesture at two doors. One is marked Management. The other is marked, functionally, Nothing. And you are invited to experience this as a choice rather than as what it actually is, which is a hostage negotiation with better catering.
Nobody says the quiet part. Nobody has to. The quiet part is that Principal and above are, in most orgs, implicitly reserved for people who work on things that are legible as systems—throughput, cost curves, platform reliability, the kind of work whose difficulty renders cleanly in a slide. The interface produces artifacts that are hard to render in a slide, because the artifact is the rendering. When it’s right, it’s invisible. When it’s invisible, it’s assumed to have been easy.
So a few years ago I decided to run an experiment on myself.
AI arrived, the entire industry’s development lifecycle got picked up and shaken, and every engineering organization on earth started rewriting its standards and practices in real time. That’s a rare kind of opening—a moment where the existing hierarchy of who-counts-as-serious is briefly, genuinely unstable. So I started as engineer one on the AI frameworks and Services team inside an organization of over five thousand engineers, with a fairly explicit and slightly embarrassing personal thesis:
I will demonstrate, in public, with receipts, that I am not merely “the UI guy.” I am an engineer who can architect a platform, lead a team through it, and orchestrate an entire technology bet while the technology is still moving.
Four years. Four end-to-end solutions, all built on a platform I architected. A team I led the whole way. Things we got right that I’d do identically tomorrow, and things we got wrong that I think about at two in the morning with an intensity I’d describe as unhealthy if it weren’t so obviously standard-issue for the profession.
And at the end of those four years, my title was the same as at the beginning. As it has been for most of a decade.
IV. The machines agree with the prejudice, which I find genuinely funny
Now, the punchline. I did not construct this punchline. I built the entire premise myself, over years, and then walked directly into it.
Building a backend service with a capable model is, at this point, a pleasant experience. You write a spec. You stratify your endpoints, split them across a worktree to parallelize, hand over clear instructions, and go make a coffee. What comes back—in Go, in Node, doesn’t much matter—is a genuinely respectable API, in something like an afternoon. The thing the trade respects most has become, of all the work available, among the most tractable to delegate.
Now ask the same model for a novel interface.
Not “a dashboard.” Something with an actual point of view, that isn’t Bootstrap wearing a new coat, that isn’t the statistical center of mass of every admin panel ever committed to a public repository. What you have entered is not a task. It is a hostage negotiation, and it will take days, and it will get personal. You will spend those days pulling the output away from the mean, because the mean is exactly what a model trained on the whole internet’s design systems is built to produce, and because “novel” and “predicted from prior examples” are, in the most literal available sense, opposites.3
Which produces the following state of affairs, and I want to lay it out flatly because I think it’s the most interesting thing in this entire post:
- The work the industry codes as hard and serious has become substantially automatable.
- The work the industry codes as fiddly and junior has proven stubbornly resistant to automation, because its difficulty was never in the syntax. It was in the judgment. In taste. In knowing which of forty acceptable arrangements is the one a stranger will understand without being taught.
- The industry’s status hierarchy has, so far, updated on this approximately not at all.
Even the machines took the backend more seriously. I built the tooling that demonstrated this and I still can’t decide if that’s a tragedy or the best joke I’ve ever been the subject of.
V. What I’m actually claiming, and what I’m not
I want to be careful here, because there is a way of making this argument that is insufferable, and it’s the way where the author is a misunderstood genius and the organization is a conspiracy of fools. I have worked with a great many people I’d describe as neither, and the ones who made these calls were mostly acting rationally inside a set of incentives none of them designed.
So, precisely:
I’m not claiming I was owed a promotion. Nobody is owed a promotion. I’m claiming that the criteria by which promotions were evaluated contained a structural blind spot that was never surfaced, examined, or written down—and that the blind spot has a shape, and the shape is work whose quality is hardest to see when it’s best done.
I’m not claiming frontend is harder than backend. I’m claiming the two difficulties are differently legible, and that legibility, not difficulty, is what gets rewarded. Which is a much more uncomfortable claim, because legibility is something an organization chooses and could choose differently.
I’m not claiming this was personal. I’m claiming that the absence of malice is precisely what makes it durable. Malice you can escalate. A shared unexamined assumption just sits there, quietly costing people their careers, being nobody’s fault in particular.
And the failure mode I’ll own: for my entire career, I have optimized for the work being good rather than for the work being seen, on the theory that the first would eventually produce the second. I want to be honest that this was a strategic error and not merely a virtue. Somebody who loves me suggested a while ago that I’m simply bad at self-promotion, and I have declined to investigate that further on the grounds that some rocks are better left unturned, particularly the ones with your own name written underneath.4
VI. Where this leaves me
I still prefer the UI. Still convinced it’s the most interesting part of the stack, and increasingly convinced—for reasons the last few years have made loud—that it’s about to be the most valuable part, whether or not the ladder ever notices.
What I’ve stopped believing is that the ladder was load-bearing. I think it was decorative. Crown molding: it implies a structure, it gestures at one, and if you removed it entirely the building would stand exactly as it does now, which tells you what it was actually for.
That’s a fine thing to conclude about a ladder. It raises an obvious and much less comfortable question about everything else, though—because a ladder is only as meaningful as the measurements underneath it, and if nobody in the building can tell you what up is being measured against, then the problem isn’t really the ladder.
That’s the next one.
↩ I’ve watched this happen enough times that I no longer find it funny in the moment, only in retrospect, which is roughly how I’d describe my relationship with the profession generally.
↩ This is, I recognize, an extremely grand way of describing the act of stopping a modal from stealing focus from a screen reader. I stand by every word of it, and I’d note that the grandiosity is doing real work: the reason interface problems get treated as small is that we describe them in small language.
↩ The steelman—that this reflects the current state of training data rather than something essential about the work—is a decent one, and I hold it loosely. But “there was less of it written down” and “its quality is harder to specify in advance” are two ways of saying the same thing, and both of them are the point.
↩ The genuinely honest footnote: some meaningful percentage of this essay is a career-long grievance wearing an argument’s clothing. I’ve tried to make sure the argument stands even if you subtract the grievance entirely. I think it does. I’d also say that, wouldn’t I.
Related
Let the Bots Do Bot Shit
A software architect on a heretical proposal: stop pointing AI at replacing humans and point it at the banal machinery no human wants to run—then quarantine the bots into their own lane and let the human internet be a neighborhood again.
Astro After Next.js
Astro's islands versus the Next.js everything-is-React default, on a real Cloudflare Pages project: a 663 KB icon package that ships zero bytes to the browser, a hand-rolled catch-all route that silently ate a prerendered page, and the typechecking gap where nothing in the build verified my React components.
University Education Isn't Trade School
A software architect on why we spent two decades funneling kids into CS as if a degree were a job requisition—saturating the market, then watching AI eat the very jobs we promised—and what a university was actually for before we confused it with a placement office.