Ask HN: Why did Frontend development explode in complexity?

257 points by nassimsoftware ↗ HN
Follow up question : Is that complexity necessary or artificially inflated?

397 comments

[ 5.1 ms ] story [ 182 ms ] thread
This will be a posting, which either receives no to little responses or will have 256 responses within the next couple of hours :)

I am sure, there'll be quite a few who'd argue that this is necessary complexity, but my take on this definitely is the latter - artificially inflated

But it's not only the web. Same happened to Java in the 2000s and is currently happening to Android. Any mainstream Java job is more configuration of Spring containers with a bit of code glue sprinkled in-between than "proper programming". As for Android, just follow a couple of Android forums where plenty of people complain about such complexity and frameworks changing "by the minute"

Aritifically inflated :)

A lot of programming seems to have turned into gluing a bunch of poorly programmed and documented systems together. I miss one of my previous jobs where I got to build a lot of stuff from scratch.
Well why reinvent the wheel with ie Spring in Java - you want well tested automatically scaling thread messaging bus for example, just configure existing stuff. Maybe its boring to some devs, but business like boringly stable tools, and they are the ones paying for our work.

Would you like that architects reinvent 'engineering wheels' with every house, bridge or tunnel and do all feom scratch just because its more fun for them? No you want well tested reliable approach, if they are bored a bit even better. Ie nuclear power plants who have some unique hybrid designs are endless source of maintenance delays and additional costs. Software devs just have much more freedom and little regulation, for now

Not necessarily reinvent the wheel, but not build the same glass buildings all across the world either. Your analogy is not that far off. Real world architecture is quite the same.
Spring is a strange example. It’s main selling point is you’re not reinventing the wheel and, instead, building on well tested and operational work already done.
That's the argument for all those frameworks.
Plumbers are vitally important, imagine flushing the toilet and poop pops out of the kitchen faucet.
I suspect a lot of it is historical. If you go back a few years there were lots of browser incompatibilities and many limitations in Javascript, CSS and HTML. To work around those difficulties and limitations many frameworks were created. Today many of the limitations of the basic technologies have been fixed but the frameworks are still here, though probably less necessary than ever. But once people have gotten used to doing things a certain way (for example using jquery instead of querySelector) they tend not to change.

This isn't unique to web development. The same thing happened with C++ and Boost, for example, where gradually the language and standard library evolved to include functionality that previously required 3rd party libraries.

But I think far more work and money has been invested in web development than other areas, hence creating a bigger mess.

My impression is that the actual user experience of most web sites, including the big ones like Amazon, has improved very little over the last decade, so it feels like all the effort put into web technologies has, so far at least, not produced a lot of value.

people expect complicated features
Complicated features don't require complicated solutions and processes.
Thats true, but people do crave complexity. If something is "too simple", often people, especially developers, are strangely suspicious of it being useful or competent. Present someone with something doing a couple things well but simply, you'll be normally greeted with a million comments of how it doesn't scale or give enough levers or do this or that.
most developers are not senselessly seeking complexity
Maybe. But they aren't consciously avoiding it either. Simplicity must be sought after.
...or developers think that. Or they pretend customers will care because they really want to play with their new framework.

Nowadays everything is a single page app, and for 90% of website/web apps it would be better (and orders of magnitude simpler) with good old server rendering. It would also be much faster.

From an application manager/solution manager perspective, I see 2 main reasons and a few smaller ones:

1. more and more complex UI. Things that used to be done in a native app are now in a browser, this has good and bad parts.

2. a lot of show off from the developers side going for overly engineered solutions. Nobody likes HTML+CSS and JavaScript anymore, if there is no cool framework with tons of tooling and dependencies than they are not happy. (yes, I know, flak incoming)

Other reasons are the complexity of dependency chains, the lack of security mindset by having hundreds of dependencies looking for a left-pad, the complexity coming from the testing of these overengineered and overly complex solutions, the move towards hybrid front end-back end management of state, rendering etc. There is also the overstretching of the frontend development role, now a fe dev needs to not just write the equivalent of HTML+CSS+JS but also containers, devops, CI/CD, all that jazz.

How much of that complex UI is managing state of the notifocations that are out to rape your brain and how much is actually useful?
> Follow up question : Is that complexity necessary or artifically inflated?

Is Javascript's complexity necessary or artificially inflated? Modern frontend development boils down to a bunch of abstractions on top of Javascript.

JavaScript as an ecosystem and language became much more accessible than ever, with all the toolings and TypeScript, it's easier to build abstractions upon abstractions; and people love to have their own version of abstractions. It's human nature, it's inevitable.
I get the impression making a web app was considerably more difficult for a solo developer pre-jQuery. For a while we had an explosion of choices, and ultimately things coalesced around React and similar paradigms. Meanwhile the per-capita productivity has been skyrocketing as increasingly sophisticated cloud services provide everything from raw key-value storage to turnkey caching and auth solutions.

Is it more complex than single-device programming? Perhaps, but the modern browsers represent a nearly universal platform with very low per-user complexity.

Internet explorer made life a nightmare. had to have if statements around most everything.

Corporate was very slow to roll out new versions. So we could get to be years behind. Things like custom Active-x apps required specific versions.

Web apps used to be just html and forms so no the complexity has skyrocketed.
Where the majority of the complexity was in the backend. Now, the complexity has simply moved.

I'm quite happy I don't need to have two different codebases in different languages for most things anymore. I'm more than happy to offload it to the browser to save me some effort, time and money.

You have to validate on the backend among other things. Honestly the only thing we have nowadays is flashier websites for the most part. Some very small percentage of websites actually require the tech that has been built despite the fact that nearly all engineering teams seem to push for it.
It's artificially inflated and I'm seeing this in almost all areas, not just frontend.

Some of the projects I've seen could have been reduced in size multiple times with no effect on the outcome whatsoever. In one instance I rewrote a GUI app and made it 15 times smaller (!), that's my absolute record to date.

Been wondering for years, so you need to actually be inventive to add unnecessary complexity, it's not that it comes for free or because of incompetence (though that too of course). And a lot of the times it looks almost as if software engineers do it on purpose, sometimes very creatively at that.

Where is this coming from? Is it because we want our work to look important?

One of the best examples of this complexity inflation problem I always see is the Redux pattern in frontends. This pattern comes with a lot of overhead, a lot of things that need to line up (Actions, Reducers, Actioncreators, Selectors, ...). And most of the time the applications that use it are completely trivial. If you remove Redux, half of the code is gone, it's faster and easier to understand and extend.
Same for MVC/MVVM and Co specifically on mobile. These things were created to teach beginners a few important concepts, mainly separation of concerns. MVC/MVVM work well on toy sample projects with 2-3 pages but can ruin a larger project. Somehow wherever I'm seeing MVVM applied there's also messy, buggy, impenetrable code around it. I don't think it's a coincidence.
MVVM: yes, in most cases. There are some cases where it's a godsend, but most of the uses I have seen are ... not entirely sane.

But MVC? That's pretty minimal in terms of what you're going to do anyway if you have functionality (model) and will be interacting with it (view). Controllers are often misunderstood, and in the case of Apple massively misapplied (Massive View Controllers).

It doesn't help that there are dozens of different definitions of MVC running around. The very clearly uses one that is different from yours.

The thing is that, whatever definition you use, you should have almost all of your code in one of those layers, a small minority on another, and shouldn't even remember exactly how to change the other (unless you start many projects). If that's not the case, your code architecture is working against you.

Agreed on that controllers are often misunderstood. I saw them to become both: a view and a model at the same time. :(
What's important to realise is that the elements in MVC are roles not entities.

So for example Views in Cocoa actually fulfil both the View and (largely) the Controller role.

Which is why ViewControllers confused me greatly when they came out. Like they confuse most of the Apple-ecosystem code out there these days. While I do understand how they got there, that doesn't make it better...

agree again.

offtopic: love your blog!

Exactly, those patterns may be good if you know exactly what you're doing.

But in all the other cases, they just make everything more complicated and harder to understand.

I've once worked with a messy codebase, it was written in a very "naive" way, but that was also the strength of that code. Every view was in one file, every action was just one method, so you exactly knew what code was executed when. We tried to refactor it, but it became complicated really quickly (the domain was really complex), so we decided to just adopt to the style. We only split up components that became to big into smaller components, sometimes decoupled things a bit, but most of the time just kept all the logic.

And this product is successfully in use for over a decade now.

I find that in larger GUI apps the best thing to have is a layered architecture where visual and non-visual parts are separated globally, not on a view-by-view basis. One advantage of this is that you can slice off your visual part and have something like a "headless browser" variant of your app. Among other things this is good for writing integration tests if you also have a backend. Same trick is impossible or very difficult to do with MVVM.
> visual and non-visual parts are separated globally, not on a view-by-view basis

Yes, yes, and YES!

This is something that confused me greatly over the last years: teams/companies I was in contact with were really struggling getting MVC to work (never mind MV*) and I wasn't...but I wasn't doing anything special, at least not that I could tell.

I would implement my model, TDD-style, put minimal views on top, possible add a view-model here and there if there was some display-specific logic that was complex enough to warrant more extensive testing, voilà.

It was only recently, partly when working with some teams that were doing modularity for modularity's sake (and MVVM for MVVM's sake), and partly when writing down Blackbird[1] that I really noticed the per-view thing.

Don't do that.

>"headless browser" variant of your app

Exactly. Do this.

The app is an object. It has an API. It knows how to coordinate its pieces. The local I/O, the remote I/O, any timing stuff. All of it. Then you plonk the UI on top of that. You can have sub-parts, but you need one piece that ties it all together, on the model side.

> Same trick is impossible or very difficult to do with MVVM.

Well, it's impossible with the misapplication of MVVM that is common today. A view model is a perfectly fine addition if you have some complex but fairly presentation-specific logic. And you put that in a testable model that is fairly tied to one view.

Instead, people have used MVVM to double down on their view-centric misunderstanding of MVC, with anemic models that know just enough to service a specific view.

Meaning any kind of cross-app logic can't go in the model. Meaning it is going to go into the view parts (or rather: the misnamed and misapplied controllers). Which is exactly where it has absolutely no business whatsoever being.

Sigh.

[1] https://blog.metaobject.com/2022/06/blackbird-simple-referen...

Does this mean we could fragment an application into, say, a low-level "engine" or "kernel" in C or Rust, an application server to handle requests to it, and the view be any of a React Native mobile app, desktop app, or convenience web API?

Please forgive the lack of background of this next question, but does this mean you do not support BFF pattern?

Have you heard of Dubray's SAM (State-Actor-Model) approach?

Curious about your replies and thank-you for your time.

> Does this mean we could fragment an application into, say, a low-level "engine" or "kernel" in C or Rust, an application server to handle requests to it, and the view be any of a React Native mobile app, desktop app, or convenience web API?

Let me present: Kotlin Multiplatform Mobile[0] (or KMM, a real mouthful I'll grant you). Something I'm very excited about, because you could do exactly that. Seems like an interesting thing to keep an eye on.

[0] https://kotlinlang.org/lp/mobile/

Sounds neat, thank-you. Have you heard of Java Cuba/Jmix?

From my limited, surface understanding, that is what KMM reminds me of: a way to define UI in Java, which means the entire stack could be in a single language (or mix of JVM languages).

> a low-level "engine" or "kernel" [..] and the view be any of a React Native mobile app, desktop app, or convenience web API

Yes, exactly that. Not my idea, of course. See for example Hexagonal Architecture. Or good old NeXT Enterprise Objects Framework, later extended by WebObjects.

> Have you heard of Dubray's SAM

No I hadn't, thanks for the tip!

He identifies one of the core problems with how MVC is incorrectly applied:

"The core issue here is [that in] traditional MVC, the action (controller) would call an update method on the model and upon success (or error) decide how to update the view. "

https://www.infoq.com/articles/no-more-mvc-frameworks/

However, he incorrectly claims that this is "traditional MVC". It is not. In fact, traditional MVC clearly forbids this, as it states that the View updates itself from the model. The View is active, you don't push data to the view.

Model -> View communication is a notification. That's it. (This is also how it is implemented in Smalltalk MVC, which is the prototypical and archetypical MVC implementation).

Thank-you for your reply. I had another question about models and the database.

It feels to me that the database tends to be more stable over time than the application: frameworks, design approach, and architectures come and go, but tables, stored procs, and views have always been there.

That said, supposing we were to start with the data model and many business rules expressed in the database first, would you reach for GraphQL to help the app manage the data it needs, or acquiesce custom db objects to provide the required data?

With SAM, I thought there would be a way to avoid BFF, while conforming to a TLA+-ish way of enforcing (the model's valid) states at all times.

I know I am handwaving a lot of ideas. Just wanted to get your input on the backend side of things.

Thank-you.

>>"headless browser" variant of your app

> Exactly. Do this.

> The app is an object. It has an API. It knows how to coordinate its pieces. The local I/O, the remote I/O, any timing stuff. All of it. Then you plonk the UI on > top of that. You can have sub-parts, but you need one piece that ties it all together, on the model side.

This is exactly what I did with all projects I've worked on. It helped that I had to target both, iOS and macOS where sharing "business logic" was crucial, so you were kinda "forced" to think about that.

To put it simply, there is one question I'm asking myself, can I delete UI and then rewrite it from scratch without updating non UIView/NSView code (just calling MyClasses i.e. my APIs)? Let's just say, if I have to write NSSortDescriptor again, that means there is an architectural issue with my code, which has to be fixed.

Out of curiosity, what's fashionable these days? As opposed to MVC?
To be fair most front-end projects have abandoned redux now. It was for sure boilerplate hell.
Tell that to European corporations. Angular + NgRx/NGXS is the de-facto gold standard there.
What were they using before?
I think Observables are much simpler to grok than some hundreds-line multi-file combined reducer/actions amalgamation.
I think React hooks are so much easier to write than observables. It provides similar functionality to observables, but without the added complexity.
I've been doing some research recently and it continues to be by far the most popular state management framework for React. The fact that there are alternatives doesn't mean that most projects have abandoned it.
Do these metrics count "no framework" as an option? With hooks, context and separation of concerns, most apps can live very well without any "state management framework" at all.
Has it occurred to you that maybe “state management” is not something you need a framework for?
Tell me you're not making complex webapps without telling you're not making complex webapps
The publish-subscribe/observer/mediator pattern is perfectly fine for state management, and doesn't need a framework. At most, a small-ish library, but you can also re-implement it yourself quite easily.

Reading your comment, I have the impression you took it as "there shouldn't be any state management necessary", instead of "state management doesn't need a framework" sense.

"State management is complex, so we used a framework to make things easier."

"Why use a widely popular, well-documented, battle-tested framework? Just have one of your senior devs build something over the weekend. This will definitely reduce complexity."

Like... I get what you're saying. But "build your own" is not a default answer for an extremely complicated software engineering topic (which, yes, state management is!)

FWIW, Redux literally _is_ a pub-sub/observer pattern implementation :) And the Redux core library _is_ extremely small.

But, that led to the community building hundreds of addon libraries for the same sets of use cases, which is what led us to build our official Redux Toolkit package to simplify standard Redux usage patterns.

This relates in no way to any statement from the comment you replied to.

Did you mean to reply to a different comment?

> [..] the most popular state management framework for React [..]

Quoted from the comment they're replying to.

> [..] maybe “state management” is not something you need a framework for?

Quoted from their reply.

Ah I beg your pardon. I read the comment in completely the wrong tone of voice.

To me it seemed like the comment was attacking its parent for investigating state management frameworks in the first place - when it in fact called out "no framework" as a valid alternative to any number of frameworks.

(I hope that made sense)

What are people using now? Good old context?
Things like react-query for syncing with server state (which can be most state in web apps) are getting popular, or smaller hook-oriented stores, like zustand, jotai or recoil for true client-side state.
Second time today that someone has mentioned React-query to me. Sign that I need to look that up finally
What's interesting is why was it so widely accepted in the first place. It's not like boilerplate reveals itself at later stages, it's right there from the beginning. I think it tells a lot about the state of the industry.
All this complexity is actually a counter reaction to frontend developers not being considered to be real developers. They went overboard trying to prove that they are.
Savage, but a very interesting take.
I think there is some truth in that thought. If they spend some of their energy into learning a backend technology, this would be much better spent effort. From my experience frontend-only developers are often very limited in their programming skills. Frontend development has its own complicated challenges, but usually the programming part is quite trivial compared to backend. And a lot of logic inside frontends would be better off in the backend (Full Stack developer speaking here).
Hi, I'm a Redux maintainer.

I'll definitely agree that Redux _has_ been overused.

But it's also worth understanding _why_ Redux was created in the first place and why it got so popular.

As a brief recap: the first major wave of JS MVC frameworks had major flaws. Angular's dirty checking didn't scale and was impossible to debug. Backbone's event-based system led to events ricocheting around the app with no way to trace what would happen when a given value changed. Additionally, manual DOM manipulation made it hard to manage ongoing changes to the UI over time.

This led to Facebook designing React to let devs write encapsulated components with predictable output and behavior, but React didn't have a solution for larger global state. Facebook later announced a "Flux Architecture" concept that tried to make larger app state updates predictable through centralization.

The React community ran with this idea and produced dozens of Flux-inspired libraries. Redux took the ideas from several of those Flux libraries, and applied Functional Programming principles, with the goal of making it easier to understand when, where, why, and how your state is being updated and changing over time.

The community then adopted Redux because A) it was the best of all the Flux implementations, B) it _did_ address the issues people were running into around state management, C) it was designed to work well with React, and D) it also incidentally helped work around limitations in React's original Context API. (I've talked about the original intent and purpose extensively in my blog posts and conference talks [0] [1].)

After that, yes, Redux _did_ get shoved into many applications that didn't need it, in the same way that React has been used for many sites that didn't necessarily require that setup.

So, we've always recommended that people actually take the time to evaluate the specific problems they need to solve in their app, and make an informed decision on whether Redux is an appropriate solution for those problems [2].

Beyond that, we've specifically designed and built our official Redux Toolkit package [3] [4] to eliminate the old "boilerplate" concerns. "Modern Redux" with Redux Toolkit and React-Redux hooks is _much_ easier to learn and use than the original Redux patterns, and we get highly positive feedback on a daily basis from folks who enjoy using RTK. We also built an "RTK Query" data fetching and caching API [5], as data fetching is the most common thing that apps need to do today.

[0] https://blog.isquaredsoftware.com/2017/05/idiomatic-redux-ta...

[1] https://blog.isquaredsoftware.com/series/presentations

[2] https://redux.js.org/tutorials/essentials/part-1-overview-co...

[3] https://redux.js.org/introduction/why-rtk-is-redux-today

[4] https://blog.isquaredsoftware.com/2022/06/presentations-mode...

[5] https://redux-toolkit.js.org/rtk-query/overview

I didn't look into Redux for a while, but RTK looks really good. That's a meaningful evolution.

I never did really complex frontend applications, but once I used React Query or SWR most of the needs for global state were gone. And so the need for Redux.

> This led to Facebook designing React to let devs write encapsulated components with predictable output and behavior, but React didn't have a solution for larger global state. Facebook later announced a "Flux Architecture" concept that tried to make larger app state updates predictable through centralization.

Can someone explain this to me please? How is it possible, that Facebook, did not have a plan from the beginning for a larger global state, even though their own app is huge? How did they solve it in Facebook in the first place? or did they started using React for themselves AFTER solving the global state problem somehow?

I genuinely want to know the answer to that.
The problem has always been immutable state. JavaScript doesn’t have ergonomic constructs to handle immutable state very well. IMO, immutability shouldn’t even be enforced by the view rendering layer. Immutability in React is enforced to cater to the needs of React’s implementation, and not the needs of the developer. It should be a choice by the developer whether or not they store their state in immutable data structures. Hooks are marketed as a means to make React into more of a framework, but the reality is that they are an attempt to smooth over the problems surrounding immutable state. Solid js also doesn’t solve this problem, even if it has more ergonomic ways of dealing with the problem.

Digging deeper, it seems to me that attempting to subvert the standard behaviour of the DOM will always produce a leaky abstraction, and it negates the benefits of working on a standardised platform.

This. While engaging in flame wars about React I have noticed that all of them start with a peculiar definition of done that, lo and behold, necessitates not only React but whatever feature if the month they are busy ductaping to it.

What we need is an honest conversation about what USERS think about spa apps, flat design, etc while holding very obviously interested parties from skewing the narratiwe.

This.

No user wakes up and says, "I gots to find me a UI built with React* today, or I'm going to cry." Ever.

Users. Don't. Care.

We keep adding tech and tools and experiences - if you asked users - aren't improving all that much.

* Or whatever technolgy being championed.

I dunno. Lots of users seem to wake up and say “Gimme a UI with rich interactions, super low latency, offline support, and real-time sync.” Even for B2B “back-of-office” software, the standards for software usability are really high, especially for new entrants.

Those kinda features are hard without a pretty complex frontend.

Not saying those things are always necessary, or that people don’t add bells and whistles where they aren’t wanted.

> I dunno. Lots of users seem to wake up and say “Gimme a UI with rich interactions, super low latency, offline support, and real-time sync

I'm inclined to disagree.

One of the most successful web apps I know is a CGI (not FastCGI) app written in Pascal and containing some 30-yo code.

100% of users I met are happy but they don't even know why. "It's good", they say.

I believe their underlying reasons are:

- the app is extremely fast. Full screen reloads are not a matter anymore with broadband internet.

- client side code is light enough to run well in crappy, old windows-based PCs running internet explorer

- lots of reports and features. The vendor's team has time to develop them since they are not busy trying to centralize stuff, fighting w/ CSS properties and other stupidities.

This! I often build Django apps without any javascript and it's so light weight that the pages render instantly. If there is some interactivity needed then I toss in htmx where needed.
The problem is that most of these front end apps end up calling out to the server all the time. So you end up with essentially the same latency of SSR with the complexity of an application split across a HTTP boundary.

I do think there's a place for real time web UIs in business apps. I spent a chunk of my career replacing green screens with web UIs. Usually ended up slowing people down because they lost the ability to chain commands.

With green screens they'd know that the navigation to change and address was like 3, 2, down, down, enter. So they'd get there in a split second. With a web UI they'd have to wait for the screen to render in between each action. Ultimately it's much slower.

So much this.

You see it with the death of paged result views, and their replacement with "Yet Another Query Lang/Search Widget". Sometimes, to a User, that God's eye paginated view of a dataset is a lifesaver, because over time you start learning it's shape.

You learn datapoint X is on page 5, and as time goes on, you can further optimize, and you gain a visceral, kinesthetic sense for the dataset/program.

You have to use it though; and you have to document it. People aren't going to just magically intuit how your obtuse arse search widget works. They don't know your data model.

Even worse, they don't know your company calls something the industry now calls "Fred" "Bob", because "Bob" was the standard before "Fred", but you're a late adopter for reasons.

Or worse, that you labelled a field "Barney" in the UI, but in your search widget query, it has to be dealt with as BRNE. Or even worse: you enter "Fred=fredvalue AND Barney=BRNEvalue", yet you end up finding out someone had a fundamental misunderstanding down the line, and it turns out fredvalue is mapping to BRNE on the backend, and BRNEvalue is mapping to Fred.

These are all examples of actual bugs I've had to squash in the last 2 and a half years; and which only get worse and worse as time and system integrations move on, because they'll tend to echo out of your system under development into other auxilliary systems like your call center IVR or CRM, or customer service tool. Now you have three disparate systems to get fixes/work scheduled for, and which all need to be done in lockstep to roll out coherently across an org.

I've had to sit with Users, watching them, learning the desire paths, then sit down and have a long talk with a designer to explain the heuristics they weren't taking into account given the people who were actually using the thing.

Compared to snappy interfaces that your hands can master, and to be honest, it feels like a lot of web app is just regression, and an excuse to justify enploying someone to wholesale change the aesthetics of the interface no matter how much of a detriment that in the end becomes to the functionality of the tool.

Nah. They never say that. Ever. At best they say cut the crap and help me get done what *I* need to do.

The point is, tech for the sake of tech is the wrong target. And once you go down that road you're already lowing your odds of having satisfied users.

> Gimme a UI with rich interactions

You sure? Because all I hear on daily basis is "please don't make me learn new shit" and "get these annoying ads out of the way". Web is so "rich" these days that disabling Adblock should come with epilepsy warning.

> We keep adding tech and tools and experiences - if you asked users - aren't improving all that much.

Nowadays, when a provider adds an "experience" resulting only in no improvement, I feel actually quite happy. The general rule seems to be (not so slowly) migrating to activelly deteriorate functionality.

Past week my bank changed their UI to show a cute animation of a hand shaking some cash in a transaction confirmation screen. And, in the process, they've removed the button to immediatelly logout after the transfer is completed -- something I used to do frequently.

It's infuriating.

It's the only way promos can happen -- adding more gratuitous useless "features" to an already-steaming pile of crap.
On one hand we are complaining about app store monopolies, and on the other hand the enormously rich web ecosystem with plenty of choice and enormous freedom is also too fragmented/bloated? What is the desired state here?

PS. Needless complexity === I don't understand it so it's useless?

It's all over techcomms too: GML / Scribe aaalllllll the way to DocBook, then DITA and S1000D. And people run to adopt those thick specs, in spite of there being zero supporting data that they in any way reduce cost . . or do anything useful[1] at all. Watch that adjective "useful".

I see it as Scientist/Technician vs Prophet/Priest.

These two pairs are solutions to a problem: the world isn't doing what I say. They can both work, or at least do better than random. The difference is that the former can explain why, and the latter can't.

The cool thing about not explaining? It makes the Prophet the only person who can evaluate the work. They have vision into the solution, and it appears only to them.

The bad thing about Prophets? If you've quantified the solution, then it can be falsified and replicated.

Wait a second . . how hard can it be to quantify a solution? It's actually really hard - particularly in things like natural language (tech comms) and visual arts (yes, front end is viz art, FIGHT ME :D). Some industries have blown up their prophets to such towering heights that they will set fire to clients and money and any other quantitative measure of value . . all in search of that One Truth (content re-use and so-called "single sourcing", I am looking at you, but I'm not even going to tease the elephant in the room that is AS9100)

People in insecure positions will always seek to turn their Technician position into a Priest position, even if they need to find some Prophet to cling to. And eventually, they might get a chance to be a Prophet too. It's like an MLM for your mind.

[1] "Structured content is the future!" Oh, is it now? How's that been working out for you last checks watch twenty years? "Hierarchical organizations are required for finding stuff!" Do you know, I think I remember the Internet Outline google publishes ever second /s. Ah, "useful".

It's very easy to see why this happens. Because nobody actually knows what they're doing.

There is no logical/mathematical theory around program design. We have no idea if we're improving in optimization, staying the same or even going backwards.

For the shortest distance between two points, we have a theory that defines the best distance: A line. That's an easy target to hit. For the best way to design and organize our programs... there is no theory. It's all made up and opinionated. Without a theory we can never truly know.

Thus we are doomed to forever move in a flat circle creating framework after framework and endlessly having progress move horizontally while wasting effort creating isomorphic patterns without ever knowing if the new pattern is better or worse.

Until the day we have a mathematical theory around program organization that can say Design A is 2.3 times more optimal then Design B. Then on that day... this madness will stop.

But until that day we're all stuck in an endless limbo mouse wheel mind fuck. I look at front end and I suspect that out of all software technologies, front end is one of the few fields that is actually moving backwards. I'd estimate 0.01x less optimal every year then I predict at a delta of 0.5x less optimal from an inflection point it starts to oscillate back towards the natural equilibrium again. Then when it hits equilibrium it will oscillate in the opposite direction again. Endless.

Python is likely one of the most stable technologies imo. It's definitely not remotely close to the MOST optimal state but it's nested too comfortably in a local optima and it will likely be stuck there forever.

"Where is this coming from? Is it because we want our work to look important?"

I am intimately convinced it could play a role, at two layers. First, at the framework layer itself: the plethora of propositions seems symptomatic of our approach to dealing with things we don't like. When confronted to the choice of walking the extra mile to improve and contribute to an existing language/framework, or building your own new thing that focuses on solving your own problem, my guess is that the more senior architects (esp. those working at licorns or GAFAMs) will choose the latter option, thus resulting in an increased offer. Also, let's not forget, being the author of a successful language or framework sounds cool.

Second, at the user layer (architect at random corp): this individual is increasingly convinced that working with the latest silicon valley approved framework will work wonders on her/his resume.

I am confronted to new software architectures on a weekly basis as a result of my job and the choices of framework/language X as opposed to Y often follows a common pattern: some architect thinks that segmenting a system into as many components/technologies as possible somehow always makes it more reliable at the end.

If I owned a software company, I'd immediately get rid of anyone showing these behaviors. But I have to admit: the bigger the mess, the more hours I can bill :)

> some architect thinks that segmenting a system into as many components/technologies as possible somehow always makes it more reliable at the end. If I owned a software company, I'd immediately get rid of anyone showing these behaviors. But I have to admit: the bigger the mess, the more hours I can bill :)

I recently greenlit a project that uses the latest Angular, C# REST APIs and a SQL server.

It's clean, it works, it's performant, it's logical and it's maintainable.

And as long as I'm still here, it's staying that way :)

(note: I agree with your approach, just making a point)

> that uses the latest Angular

But what's the migration plan for the next time Angular goes through a massive ecosystem migration and suddenly you're staring down the barrel of being massively out of date, or investing anywhere from days to months of work running just to stay in place? This is what actually seems to be the problem to me, not just in frontend either: very little is stable, and you end up piling hacks upon hacks just to try and stay up to date. People also pick new tech after being burned by previous tech doing these massive ecosystem-wide migrations and seeing how painful it is.

I wish I knew the solution :)

Let me ask you: what is the alternative? Life cycle management and building software go hand in hand.
Speaking just for Angular, things seem to have settled down a lot. The applicaton was originally created under 13 and has been migrated to 14 and just recently to 15.

Those upgrades were quick and painless. Some new features come with each update, but aren't required to implement them and the existing code runs fine under v15.

Because the browser nowadays is an "operating system" that needs to be capable of handling all manner of dynamic software: maps, video, image editors, games, etc. I haven't done Windows development, but I assume browser-based development complexity will continue trending towards essentially the same complexity as developing e.g. a Windows program.
TWenty years ago windows development was a lot simpler than modern browser applications. Fire up visual studio and create a new winforms project.

You could literally drag and drop your way to a modest application with only minimal programming 'under the hood' for the business logic.

I still don't think anything has surpassed the usability of winforms for a developer just wanting to get something done.

The browser is powerful enough now that one could replicate this if one wanted to. I don’t think it’s the pinnacle of software development, but it had some advantages.
This seems true in the same sense that every language is theoretically equivalent because they’re Turing complete: technically true.
The difference is that winforms basically had one way to do everything which expedited development because it skipped all of the infinite number of stupid small decisions and libraries that must be cobbled together in a typical SPA.
Win32 could do it all. And in windows there was often a different way to handle things like video across each major OS version. Yet still, I feel it was simpler! Crazy!!
Nothing surpassed Delphi from early 2000s. Not even WinForms.
Can confirm. I love winforms. Convinced that even the most hardcore Unix devs are missing out on the sheer joy of being able to double-click on a form you just dropped into an editor and seeing it automatically add an event handler for the common case of whatever type of UI component it is. (Buttons are onclick, inputs are ontextchange, etc.)
I think QTCreator provides a similar experience, but I haven't used it in years and might be wrong.
Glade did that decades ago for GTK+ apps too. A WYSIWYG UI editor which prepared all the UI boilerplate code for you automatically.
There are RAD IDEs for popular Unix frameworks like Qt or Gnome and probabyly much more I haven't heard about.
XAML in Visual Studio is similar. You can put in the call to the handler, then "Go To Definition..." and it will create the handler for you.
There are plenty of website builders that don’t require you to code. Platforms like squarespace or wix make it really simple.
drag and drop forms from 20 years ago assumed a desktop PC. Today your form has to work on mobile
Help me understand why that is significant, or is that your point, that the viewport changing shouldn't be a big deal. Not following.
The drag and drop your parent comment mentions is used for creating the WinForms application, not for interacting with it. Creating the application is still done on a Desktop PC.
Correct, but the form itself was always a fixed layout, designed for desktop, not a responsive layout where things changed based on the size of the user's display and the input methods available to them
This was available way before with Delphi and now Lazarus. And it produced single native exe that did not require install.
I do not think that you would be able to do ActiveX, COM, OLE, MFC, C++ after 2 weeks of bootcamp. Yes, Delphi and Visual Basic simplified many of it but there were still many challenges to develop and ship your software. Just shipping alone and dealing with installers was a challenge by itself. Now compare it with a browser tab and a single click that deploys your code across the globe so it event can run in space on ISS.
But here's the thing: you didn't needed COM or ActiveX or MFC in many cases. You could literally wire up and build an up pretty effortlessly. With webdev today we jump directly to very complicated things when 90% of the time they are not needed.
For simple things we still have Excel and Ms Access where people continue to build simple UIs for personal use. At my previous job, our CFO build own framework (Excel) to manage and automate financial reports (which makes him a full-stack developer based on industry standards)

I guess the frustration comes from the fact that historically Web started as a set of static HTML files to create/publish documents and we inertially compare todays Web with it but we if stop comparing apples with oranges than it becomes apparent that:

1. It's never been simpler to create and publish web content 2. It's never been simpler to build/ship/and distribute software

Complexity arises when people (given many options) pick wrong tool for a job.

Picking the wrong tool but also cargo cults. If everyone is a X-developer and is using Y and you are working in X you start to wonder if you should be using Y, right?
My 15 year old Delphi program which runs the whole factory still hasnt been replaced, despite the company and IT staff growing by 10x. Its now taken 4 years, 3 IT Managers and 2 consulting firms to decide Delphi is archaic and it will all be re-written using "cloud and modern frameworks". They have given the team of 3 developers 2 years to do it. Considering they have not managed to keep a developer or IT Manager for longer than 18 months, I would say good luck. I really dont know how anyone gets anything done these days.
But developing a windows program is simpler.
I'm a Windows developer and as such I'm biased, but I think Windows apps are dramatically easier to write than web apps. I still use WinForms professionally to this day. Productivity is absurdly high. The number of concerns to worry about is low. The framework has been stable for 20 years and I know all of its quirks, which never change. Fads are ignored. We can zip around with amazing speed.

On the other hand, our apps are:

- Ugly looking

- Dated looking (this is different than ugly, but our apps are both)

- Full of UI jank (too many WinForms controls take their sweet time painting on the UI thread)

- Non-server-based

- Non-cross-platform

- Non-sandboxed

- Installed from downloaded file that gives scary warnings in your browser when you try to open it

These downsides hint at some of the reasons why I think web-based development is necessarily more involved than for Windows apps.

A large part of the reason people ignore your model for business use, where the target platform is locked down to a single target, is the perceived need to run their software on any given piece of hardware.

That's a question that really aught to be answered. If the business application only requires Windows PCs as a target your design wins out despite the perceived shortcomings.

Would solving these painpoints be a market? Sounds interesting to delve into.
Most of them can be solved by using a more modern but similar toolkit like Jetpack Compose, JavaFX etc. Then you have distribution, but to get rid of the scary warnings just requires you buy signing certificates. Distribution is still a pain after that, but that's why I built Conveyor, to simplify it.

Going further would require remixing bits of Chromium to create a browser-like thing with a sandbox, but which is much less opinionated about what runs inside of it.

Problem is, for there to be a market requires that devs (or someone) pays for it. How much would you pay to be able to not write a web app?

>I'm a Windows developer and as such I'm biased, but I think Windows apps are dramatically easier to write than web apps.

I agree that the developer-facing usability of a good desktop GUI toolkit runs circles around whatever webdev is these days, but the barrier to entry for a completely new programmer is certainly a lot higher than HTML.

That's why I miss good ol' VB6.

Spaghetti code? Yeah, not only that, but the whole pasta menu. On Error Resume Next.

The barrier to entry were none to zero.

Yes, the browsers export a lot of capabilities to the frontend. But you point no reason why the frontends must use those capabilities.
IMO it's mainly Google and Chrome/ChromeOS trying desperately to keep people away from the competing Windows and Apple ecosystems, which requires that the browser do essentially anything a stand-alone program could do. This doesn't explain why there are a million JS frameworks, but it does explain why the browser has ballooned in features and complexity over the years.
>This doesn't explain why there are a million JS frameworks

Not sure if this is a valid answer, but I would assume that both Microsoft and Apple provided decent and easy to use frameworks to build applications on their operating system. This setup a particular amount of vendor lock in, the library is already there and doesn't need downloaded/installed making it easy on the end user.

On the other hand, frameworks were not provided by the browser manufactures initially. Also, everything is downloaded so 'include foo.js' is just as easy as 'include bar.js' opening up a vast ecosystem of frameworks.

The first sentence is a valid reason:

> Because the browser nowadays is an "operating system" that needs to be capable of handling all manner of dynamic software: maps, video, image editors, games, etc.

If frontends didn't use the "OS" capabilities of the browser, how would one build a multi-user real-time text editing app like Google Docs?

Edit (and off topic): Writing this comment gave me flashbacks of using Mapquest online for driving directions before smartphones. You had to print the directions out and bring them to your car on a piece of paper. It worked though!

A couple of months ago I had to develop a whole CRUD GUI in, wait for it...Excel, using VBA.

It was very much like designing desktop programs some 20 years ago using WinForms, which was actually a piece of cake using the designer tools that came with Visual Studio etc.

It's shameful that creating programs in Excel is such a smooth ride compared to even the most trivial web app. But of course, the web app must be compatible with a billion of other things, compared to Excel and VBA.

Why? I think mainly FOMO. When react was out with the blessings of Facebook people wanted to use the same library. Of course most people didn't really care/understand that their internal crud app for editing invoices wouldn't need that complexity.

I think my answer should answer your second question: This kind of complexity is actually needed on some apps but these apps are a minority.

Programmers love shiny new things and most managers aren't technically competent enough to lease them...

> these apps are a minority.

I disagree with this. Almost all front-end projects I've worked on in the last 10 years or so have had some requirement that made pulling in react a better choice than trying to push back on business and/or get buy in to do everything server side. Providing users the kind of tighter feedback loops for their workflows is only possible with JavaScript.

You don't need to do everything on the server side. You can use Svelte or Solid.JS and have the same DevX as a framework, while compiling down to lean and blazing fast JS code on the client.
(comment deleted)
JavaScript in proper doses and places? Absolutely. Agreed.

But that's not the same as taking on a trendy library (e.g., React) and associated tooling...unnecessarily.

And this is why half of the internet is borderline unusable. Page layout jumping around for 5-10 seconds after what appears to be a full page load, buttons simply not functioning, and god forbid you try to use the back button. I know some expert will say none of those things have to happen and has nothing to do with react, but the reality of it is that these things are incredibly common in modern front end development, and I blame all the over-engineered frameworks.
Or simply wanting to browse without JS enabled.

Like 30% of pages just give me something along the lines of "enable js to make this site work"

> And this is why half of the internet is borderline unusable. Page layout jumping around for 5-10 seconds after what appears to be a full page load

This is not why half the internet is borderline unusable. React will happily do a full page render in under a second (including network load time). The primary reasons for that are:

1. People writing code that does many network requests in series. 5-10 seems to be not uncommon for many apps.

2. Adverts and as SDKs.

The app I inherited at my last job was a huge 2MB bundle (due to including both the firebase SDK and a large charting library), which I assumed was the cause of the slowness (it was taking ~3-4 seconds to load). But it turned out that was serial network requests that were slowing it down. The app is still 2MB (we made good progress on removing firebase, but hadn't quite gotten there when I left) but it now loads in around a second.

Also add in cookie banners, analytical tracking, newsletter popups.

React is a small library that loads quickly for most people.

It's a mix of this FOMO and a lot of people not knowing how to wire up AJAX well. I've seen entire teams reach for react just because there is a portion of the page where some AJAX was required and react is the only way this new crop of devs knows how to do DOM stuff with server side effects.
In what way is react related to ajax calls? I don't get it :(
The GP is saying that people use react as an ajax abstraction library.

It does make some sense. People used to use jquery exactly that way, and react provides an even better interface for ajax. I wouldn't be surprised if most of the usage of react is there just because people don't want to query their servers by hand.

> react provides an even better interface for ajax

how does react provide an interface for ajax? react does literally no calls at all...

I feel like 50% of the people complaining in this thread have never touched react or their last interaction with frontend code was jquery 15 years ago and they're still carrying those learned paradigms around and applying them to every new framework/ frontend lib they come across

Just want to highlight something from my original post:

> react is the only way this new crop of devs knows how to do DOM stuff with server side effects

DOM stuff with server side effects, they think they need react to do dynamic DOM stuff, especially if that dynamic DOM stuff affects server side state. So this isn't just about AJAX

React today, Angular before that, JQuery, Knockout, All the gloriously bloated .net AJAX controls from Webforms, etc. There's been ways to wrap AJAX calls pretty much since XMLHttpRequest was implemented.

I'd argue "Wiring it up well" is a task better suited for these vetted and highly used libraries than rolling your own code in vanilla JS.

Difference being jQuery was well suited and really necessary back in the day. Browser incompatibility meant that pretty much any non-trivial DOM operation needed to be wrapped by jQuery to be done safetly. Now every browser is just chrome except for firefox and firefox and chrome have played nicely standards wise for nearly a decade now.

Vanilla JS being viable on the frontend without jQuery or some wrapper probably didn't happen until HTML 5 so around 2014 by my reckoning.

I don’t think react valued simplicity. It didn’t have an official store for years and still lacks CSS solutions out of the box but it seemed to be the only way to do components so people used it.
tailwind is the best utility css library to use with React, you can make components with Angular, React became more popular than Angular because it didn't introduce new concepts like dependency injection and stuck closer to ES6 standards
Tailwind got popular because react doesn’t include CSS in components. Angular 1 wasn’t components based and only three people ever used angular 2.
no tailwind became popular because it introduced the concept of "utility css" and was the pioneer of it, if React included css in the components it would have looked like styled/inline javascript or scss/less or css modules, developers do not write their own classnames with tailwind
Utility CSS is the mixin pattern and was widely used for a decade before tailwind existed. This confirms by believe that tailwind is mainly used by people with little to no CSS experience.
I still do a mixture of jQuery and whatever I learned from modern JS. I totally missed the boat on everything else. I still render server sided, and rarely run into any issues.

I can simulate any kind of asynchronity with the server trough websockets or boring but effective polling.

It works for me, yet all job offers I see are looking for react or whatever Devs with rails experience. It's like JavaScript totally took over.

For JavaScript, two main factors both driven by fairly mundane and well accepted SWE principles:

1) npm encouraged small, "single responsibility" packages/libraries

2) developers are encouraged to never "reinvent the wheel", leading to them to pull in these libraries without considering the tradeoffs

In other engineering disciplines people are taught to consider tradeoffs more than in software engineering.

The tradeoffs of depending on npm packages are:

1) You don't need to reinvent the wheel, i.e. you can build very feature-rich applications at high velocities

2) Tracking, researching, integration, maintaining, and (for longer lived projects) migrating from package-A to package-B can cost way more time and energy than you'd initially think

3) Almost all packages are open source, so maintained in an ad hoc way by the contributors to the project. Even the biggest, most cohesive, well planned projects under the umbrella of tech megacorps sometimes fall into stagnation and maintenance hell. "react-scripts", which underpins the de facto standard way to bootstrap react apps "create react app", hasn't had a patch version released since Facebook pivoted to the Metaverse.

Answer to follow-up:

No, you can absolutely write modern, feature-rich front-end applications without any dependencies. You'll spend significantly more time writing lower level code allowing you to render your data into some kind of view, manage form inputs, app state and routing, but if you're disciplined and determined it's totally possible to do.

I think it's generally caused by a few issues:

1. UI development is hard to do well. Throughout my career I've seen complexity explosions in C++/Win32, C#/WPF, and JS UIs so this isn't a new phenomenon

2. It's always easy to develop the correct UI in hindsight once all the requirements are known. When starting out it's hard to know what will be needed or not and this leads to overly complex solutions

3. The browser as a platform has historically been painful to use due to a lack of good standard library

4. JS in particular has a low barrier to entry, so a lot of folks start there and learn as they go. This leads to picking the wrong tool for the job due to lack of experience

> 1. UI development is hard to do well. Throughout my career I've seen complexity explosions in C++/Win32, C#/WPF, and JS UIs so this isn't a new phenomenon

The people who complain about current front-end complexity are almost always back-end devs or people who don't touch front-end. However, almost every veteran dev who has developed UIs across many media and environments repeats your point.

Long time front end developer here.

This is pretty accurate. I would rank your issues a little differently though.

I think what's different here from other front end development are items 4 and 3.

So 4, 3, 1, 2; I guess.

I think the Frontend is mostly what gets promoted by Sales and Marketing when selling the product. The complexity results in trying to exactly meet what they request, or give them enough to talk about being new in the product. Performance improvements for the most part can only take up a few lines. New features, on the other hand, can take up countless pages if needed.
Expectations have increased a lot in web development. When I first started working, web front ends for business applications were ugly. They were designed to do the job and nothing more. They might also be hard to use without a manual. These days the designs I get given look pretty and have simplified interfaces for the user. The designs never use native elements and often invent novel UX interactions.

Back when I started, the go to front end wasn't a web app either. It was some GUI on windows which involved pretty much the same level of complexity as we have today on current web apps. So maybe the question isn't really "why did front end development explode in complexity?" But really "why do we expect front end development to be simple when asking for complex UX?"

1- As @tgflynn mentioned: historical complexity

The web was made for publishing text, not making rich apps. But it turned out to be exceptionally good for publishing SaaS. So we continued to pigggy back on it. Working directly with the DOM is too verbose, hence nobody wants to touch it.

2- Service oriented architecture

When mobiles became a thing around 2008, normal MVC apps with some AJAX would not cut, because mobile phones needed their own UI. Hence REST based approach became more popular. Things like React and Angular (or Backbone and Knockout) filled that void.

3- UI is an evented runtime

I think of UI as a small Kafka because it needs to handle events (from the user, from the browser window, from OS etc). This makes managing state tricky. To manage this complexity, the community comes up with libraries like Redux. This creates a gap for developers working at a smaller scale. With a small app, you might not run into issues arising due to event management, you might not run into race conditions. But since big companies use a particular library, small companies start using it too. This adds to the bloat.

Is there a fix ?

I think so. But it will include developers thinking outside the browser (or maybe the browser starts thinking outside the DOM?). Libraries like Hyperview and DearImgUI exist and are being used in production. Games are a good example. A game engine can render a complex scene with 100s of moving entities at consumer grade hardware. At the same time websites suffer when rendering large list views.

At the end, FE is a political landscape. A large majority of developers and companies are happy with the current state of tooling. Unless an influential figure pushes for a better UI standard, we will continue to write React.

>Working directly with the DOM

I think this is the fundamental problem. The data structures you work with are different from the data structures displayed. Almost every framework out there is there to solve this problem in a different way.

(comment deleted)
Consider how desktop apps have basically disappeared. They're all in the browser now.

Also, ask yourself what the difference in UX is between serving templates vs. something like React. Are you not getting something in return?

There may be some artificial inflation but think about websites from 10 years ago.

It's a combination of:

- Fast Fashion for web sites. Users are kinda like kids in a toy store, always jumping to the newest & coolest & shiniest things. OR - at least the suits making the calls are far-too-often convinced that they need the newest & coolest & shiniest web site, to compete for users.

- One-upmanship among young male web developers, who always want to be working with newer / cooler / yet-more-complex technology than the next guy. And how very convenient that newer, cooler, and more complex technology tends to pay far better, whether it's needed or not.

I disagree with the premise, things have gotten a lot simpler.

I think you need to make distinction between website and web application. The latter came later and is by definition a lot more complex, I assume this is mainly where the premise originates from.

But having gone through building websites with frames, tables, png's for box shadows and border radius, jQuery and php based web apps, and having spend many days making my grunt/gulp/webpack config work and supporting IE, I can with great certainty say things have never been easier than they are now.

Now, is it necessary [to build webapps]; Yes. Usability expectations have gone up, the level of details and polishing has gone up, more interactivity, and more sophisticated visual elements. Webapp now do things native applications could not do back in the day.

Web applications don't all have to be Single Page Apps.

That's where most of the unnecessary complexity comes from. Unneeded SPA.

That's not less complex, that's moving complexity to a different place with different problems and constraints.
People wanted applications and app-like behaviour in the browser. And browsers are uniquely uneqipped to deal with that:

- the core if the web has been, is, and will forever remain a system of displaying static text with a couple of images. You as much as look at it funny, and it needs to re-layout and re-render the entire screen

- there's no standard library to speak of

- there are no standard widgets and controls to speak of (https://open-ui.org/ is twenty years too late)

- there are no easily accessible ways of handling state

- almost every single API that the web provides is either underngineered, or overengineered, or badly designed, or all of them together

- the web rarely provides a comprehensive and/or a generic solution or an API. It's a hodgepodge of one-off hacks often needed to cover deficiences in other hodgepodge hacks

So, to make the web even remotely app-like, you need to solve for all these issues, and that's before you even start writing a single line of app logic.

And on top of that you have language evolution and people wanting to use features of tomorrow today.

Most of the state of application used to live on the backend but now that has transition to the frontend. Dealing with the state of application is difficult because of edgecases and side effects, React can handle many different domains mobile, tv, and website. Of course development will be more complex with more target domains.
The main reason is easy “to plug and play” various tools, i.e react, websockets, graphql, webpack etc. That’s not related to frontend only, but kubernetes devops are also crying from complexity.
I've done frontend since IE6 was the major browser. Back then most of the time was spent using hacks to work around the limitations. No rounded corners, no opacity, no grid, etc. As it got easier, with better adoption of the web standards and better tooling, frontend-devs were able to do more. But I feel as REST and GraphQL got more adopted a lot of the complexity moved from the backend to the frontend. The frontend part is easy these days, but working with the backend is the hardest part of being a frontend developer.
Frontend was always complex, being web, mobile or desktop apps. It is following similar cycles from decades ago. Winamp[1] in 1997 made their own UI using custom draw in Windows because those components and level of customization didn't exist in the standard API. We can historically observe these cycles of complexity and technology changes only looking at Windows toolkits: Win32, MFC, QT, Silverlight, Windows Forms, WPF, etc.

But the other reason is that we don't have stable tools and the right abstractions to build a UI/UX for dummies so there is lot of reinvention.

Because nobody built a good UX/UI for dummies that hides this vast complexity?

[1] https://en.wikipedia.org/wiki/Winamp

Indeed, the devs who dismiss the complexity are the ones least suited to solve for it.