Frontend Isn't Easier Than Backend — It's Hard in a Completely Different Way
After spending so long in this circle, the most common complaint I've heard is: Isn't frontend just drawing pages and calling APIs? What's so hard about it?
Many backend developers, seeing how frontend scaffolding can build a beautiful admin dashboard in two minutes, often get the impression: The barrier to entry for frontend is extremely low; any intern who can write HTML can do it.
If you're just taking on outsourced work, writing an internal reporting system that will only ever have three visitors, then frontend really is simple. But if you're responsible for a commercial system with a million daily active users, involving complex interactions and real-time data flow, then the engineering complexity faced by frontend is absolutely no less than backend distributed transactions.
The difficulty of frontend and backend is simply not on the same dimension 🤷♂️.
Backend difficulty lies in data scale 🫵
Where does backend code run? Generally, it runs in extremely stable Linux containers. The server's CPU count, memory in GB, network bandwidth — everything is absolutely controllable. If performance hits a bottleneck, the standard backend solution is clear: add machines, add caching, shard databases and tables, smooth peaks and fill valleys.
Backend code faces an extremely stable environment.
But what about frontend? Frontend code is bundled into a blob of obfuscated JavaScript and thrown directly into all sorts of browser environments.
You have no idea whether your code is running on the latest iPhone 17 Pro, or on a low-end Android phone from ten years ago with a cracked screen and only 2GB of RAM.
Backend systems are closed and stable, while the frontend runtime environment is uncontrollable.
In the deep end of frontend, 80% of our energy is not spent writing business logic, but fighting against this extremely hostile browser host environment 🫡.
Fragile requests and out-of-control race conditions?
Take the simplest example of switching tabs to load data.
From a backend perspective, you just need to write the SQL correctly and spit out the JSON. But in the real frontend engineering field, this is an uncontrollable scenario.
What would a junior frontend developer do? User clicks Tab A, request A is sent; user clicks Tab B, request B is sent.
If this happens in a weak network environment, request A might return later than request B due to network jitter. Then on the user's interface, even though they are currently on Tab B, the screen renders dirty data from A. This is the classic frontend Race Condition.
If you ignore this and let this dirty data pollute the browser's memory, at best it causes page disorder, at worst it directly triggers financial display failures.
Unreliable runtime environments
Many backend engineers can't understand why the same standard logic runs perfectly locally but crashes completely upon deployment.
Because backend code always runs in an extremely pure, isolated Docker container, where no one can casually interfere. But frontend code? It runs in thousands of different browser runtime environments.
A user might have 15 extremely rogue Chrome extensions installed. Some extensions silently intercept your normal network requests; some translation plugins forcibly tamper with the DOM nodes on your page, directly causing your React virtual DOM tree diffing to fail, resulting in an instant white screen crash.
Or, your page is forcibly embedded in a crudely built domestic Android app's WebView, where the app's underlying layer has arbitrarily rewritten JavaScript's native standard APIs, causing your standard functions to throw errors directly 😖.
When a mysterious white screen appears in production, the backend developer checks the logs and says: The API is fine, the data was sent down.
At this point, the frontend architect sifts through a pile of chaotic error logs, checking one by one whether the user's ad blocker (AdBlock) mistakenly killed a core business JS file, or whether some obscure Android browser doesn't support the latest ES syntax specification.
Frontend engineering capability is essentially writing all kinds of compatibility code. You must assume that your code's runtime environment is full of uncertainty, tampering, or unreliability, and then, within this unreliable environment, forcibly build a seemingly perfect business system.
Don't measure engineering depth by syntax
Why do many people think frontend is simple? Because all the dirty and tiring work has already been silently solved at the bottom layer by the V8 engine and various modern frameworks.
What you perceive as simplicity is because experts have shielded you from the browser's rendering pipeline, the scheduling mechanisms of macrotasks and microtasks, and the reflow process when the CSSOM and DOM trees merge.
Backend solves problems of system depth and data consistency; frontend solves problems of environmental diversity and human-computer interaction boundaries. The two are on completely different dimensions in terms of engineering difficulty.
So stop arguing about which is harder. If a backend developer looks down on frontend, it means they've never seen truly complex client-side architecture; if a frontend developer thinks they're better than backend, it means they've never experienced a P0-level online data meltdown.
Isn't that right?
Top 1 of 2 from juejin.cn, machine-translated. The original thread is authoritative.
This article seems to have been published before.
No, we only talked about frontend before.