Comment by ehnto

8 hours ago

I don't touch frontend very often anymore, but you could see the writing on the wall for complexity when React took over and newer devs were working exclusively in that abstraction.

Unlike other abstractions where things get tidied up and more simple, React is much more complex than the technology it's building on. Necessarily, to enable it's features, but none the less it is a consequence of this that when all someone knows is React or other frameworks, things get overengineered. They didn't realise it could be so much simpler if they just knocked it back a layer instead of climbing higher and higher.

FWIW I've been writing UIs using plain JavaScript and the DOM API for like 15 years and at a certain scale, I always ended up building an ad-hoc framework or being disgruntled when I had to reach for any of the pre-React UI frameworks whose APIs and approaches I didn't like. React changes this, nowadays I either start with pure DOM and then rewrite to React or just start with React. I see a lot of hate online for React these days and I agree with probably 99 % of it, but the problem in my eyes is not React itself, but the ecosystem that spurred around it. If you stick to just React and take some care with your craft, React is a joy to use IME.

  • I work on a React based web app in my Day Job and have genuinely enjoyed it.

    That said, it always feels like so much boilerplate to get up and running for a greenfield project (and things like NextJS or even TanStack Start add a lot of things that might be overkill for a simple web app).

    For some vibe coded side projects with Claude, I’ve been working with just using handlebars templates with Express and it has been pretty glorious!

    I don’t think I’d recommend building a complex web app this way, but for some mild JS interactivity, form submission, etc, handlebars works.

    Bonus: I find it much easier to get 100 across the board on Lighthouse scores this way.

    • > it always feels like so much boilerplate to get up and running for a greenfield project

      This is why I love Bun + React. The setup is so easy I can do it off memory. I always hated boilerplate, templates etc. so this is a huge selling point for me.

  • Not everything needs to be a SPA. I genuinely believe that the web would've been a much better place today on most important metrics (performance, simplicity, accessibility etc.) if this SPA shift would've never happened. The opportunity cost seems massive to me.

    • Most software I've used could have been a few hundred lines of PHP. But then they'd be done in like a day, which is great if you're a business owner (and the reason Pieter Levels uses PHP, for example), but not so great if you need to get paid to keep churning the code indefinitely (i.e. most people's situation)... and ideally hire all your friends to help too ;)

  • Personally, I like to look at the source for a page. And that, for anything React, winds up being useless (<go-suck-an-egg-because-EVERYTHYING-is-loaded-dynamically/>). I find React very hard to debug whenever anything doesn't work as expected.

> when all someone knows is React or other frameworks, things get overengineered

The next level annoyance is that everybody just assumes React to be the default for everything.

Check the Shadcn website. The landing page doesn’t mention that this is a React-only UI library at all. Same with Radix. The marketing sounds like a general-purpose UI lib. You gotta dig around a bit to realize that this is React-only.

  • my brain for whatever reason won't accept react it's just instant ejection. i was there in the before times all the way up till jquery became uncool and i just tuned out of front end entirely once react and all the stuff driven by facebook became so ubiquitous, my soul just does not want to dabble in any of it. i think im mostly just appalled at what feels like over complexity that might've made sense over a decade ago but perhaps im waiting for a more satisfying paradigm to come along. i dunno. i had some sparks of joy tinkering with golang to build ssr stuff, i dont keep up with wasm at all but i hope its cruising along.

    i wonder if what im after is like some kinda dead simple easy to use declarative front end api that can be built from a backend, something like streamlit or nicegui that has great ergonomics and is easy to maintain but scales better and has better state mgmt than streamlit & puts all the power of a general purpose programming language right there with it. i love compiled things i hate setting up environments with runtimes and stuff.

  • I've started straight up being doubtful of every UI kit until I see in the docs a HTML or non-React example.

For what it’s worth, the point of React is that you can just fix that Radio component to be an input (if that makes sense) and it’ll just be an input.

React gives you boxes to put stuff into but you decide what to put into them. Then React ensures that you can change what’s in those boxes without breaking anything. That’s the power of component abstraction.

  • > That’s the power of component abstraction.

    Yes. But React isn’t the only way to do components. Unfortunately, to the inexperienced, it is.

    • What are some much better ways to do components?

      React with is so prevalent because it's a deep local optimum.

  • So is a span or div element? What am I missing here?

    • The parent comment is seemingly blaming React for the decisions of Shadcn for some reason.

      There’s nothing about React that requires you to overcomplicate your DOM (unlike many other UI frameworks).

      2 replies →

I guess it depends on your definition of complexity. Being able to think about your UI as a function of state is a lot simpler than dealing with mutability, coordinating imperative updates all over the place, etc. React’s core idea is simpler than the paradigms it replaced. By simple, I mean as in “Simple Made Easy”[0].

[0] https://m.youtube.com/watch?v=SxdOUGdseq4&pp=ygUQc2ltcGxlIG1...

  • React is not simple (preact is) and what's worse, it gets more and more overengineered in order to solve the problems they have themselves created (accidental complexity in your video).

    Sadly, accidental complexity is a common theme among react devs, not just ui libs, but also react-router, redux, redux-form, even tanstack useQuery() is way over-engineered and the core idea can be implemented in <50 lines and then you own the code and can make project-specific changes.

    Maybe that's the biggest issue after all, people being lazy, expecting to do npm install and being able to reuse everything in any situation. Except that it almost never work like that and a lot of damage is done in the name of it... </rant>

    • Well, to be fair, Preact is what I use. I use the name Preact annd React interchangeably when discussing tech, but I agree Preact is the simpler and preferable of the two. But, in the context of this thread, both provide a nearly identical way to model UI.

I don't think this is specifically a react problem. The problem is that people don't want to learn what modern CSS can do, or write it themselves (see Tailwind), and most new frameworks make it easy to just sidestep that with div soup.

Some of us _like_ CSS, and try to use as much of it when possible, but I feel like we are few and far between. I use react to manage the state of my app, but that doesn't mean I have to make a 27 div component to style an input.

The big problem is trying to convince the rest of the team that they should learn and use CSS.

  • I agree it's not just React - I think a lot of people simply do not know what CSS can do nowadays.

    I do like Tailwind (I guess it fits with how I think). But to make good use of it you _do_ need to know how CSS works (for example, using variant selectors for picking out child elements, using container queries instead of global breakpoints etc).

    One addition - I learnt a _lot_ about CSS by reading [Every Layout](https://every-layout.dev/).

  • I really don't understand Tailwind. I heard great things about it, and then I tried it and it seemed like setting style="" on all elements, but with extra steps.

    Did we go off semantic CSS and returned to setting properties on each element, or was I using it wrong?

    • You aren't using it wrong, the only thing tailwind does better than 99% of devs is having default values that both look nice and mesh together well.

      Utility based CSS has been around as long as classes have, tailwind is just one iteration of that. GitHub use to have a utility css library as well before switching to their new design.

    • CSS is a little too low level for most web app design, Tailwind is a bit higher level and more concise than its CSS equivalent. It also has a bunch of sensible defaults for colors, sizes, spacing, and type.

    • If you're experienced with or like the way CSS works, and you didn't like Tailwind, then you were probably using it correctly.

    • > and it seemed like setting style="" on all elements, but with extra steps.

      And extra benefits.

      Generally more concise on the common usecase, but more importantly you can combine and use media queries, which can't be done with inline styles alone.

You make a good point. From a philosophical point of view, abstractions should hide complexity and make things easier for the human user. It should be like a pyramid: the bottom layer should be the most complex, and each subsequent layer should be simpler. The problem is that many of today's abstractions are built on past technology, which was often much better designed and simpler due to the constraints of that time. Due to the divergent complexity of today's abstractions and unavoidable leaks, we have a plethora of "modern" frameworks and tools that are difficult to use and create mental strain for developers. In short, I always avoid using such frameworks and prefer the old, boring basics wherever possible.

  • > divergent complexity of today's abstractions

    The vast majority of websites and apps do not have complex divergent abstraction needs.

    Some developers however require complex divergent abstractions in order to baffle brains and collect paycheck.

  • I'm struggling to form a definitive statement about my thoughts here, but I'll give it a try:

    Every (useful) abstraction that aims to make an action easier will have to be more complex inside than doing the action itself.

    Would love for someone to challenge this or find better words. But honestly, if that's not the case, you end up with something like leftPad. Libraries also almost always cover more than one use case, which also leads to them being more complex than a simple tailored solution.

    • I think of it as: adding an abstraction relocates complexity away from what you want to make easy and moves it somewhere else. It does not eliminate complexity in total, it increases it. The best abstractions have a soft edge between using them and not using them. The worst are like black holes.

  • The problem is also that every other year contracts/paradigms/... are broken, introducing bugs in libraries and documentation.

It was fine when it started, it's the addition of useEffect and hooks that messed everything up. Although normaly I prefer functional, for react classes were 100 times better

  • Hooks were fine, but their implementation in React was barkingly insane. Vue's notion of "composables" is very similar, but not dependent on order, so you can use them in conditional statements without breaking the world. I don't even want to think about doing a complex Vue app without the VueUse library.

  • I know people love to make UIs stateless and functional. But they just aren’t. IMO UIs are fundamentally a bunch of state, graphically represented. So naturally all of the functional frameworks are full of escape hatches.

    I’d rather have a honest framework than a chimera.

    I have not followed SwiftUI recently but when it was introduced I quite liked to have the main composition in SwiftUI and then writing more complex components in pure UIKit. Both could be used what they are best suited for. But trying to shoehorn good interactivity into a SwiftUI component always ended in horrible code.

    • What about Elm? I think most people could grasp the elm architecture in an afternoon. To me this MVU style is pretty much perfect for UI.

      I think a lot of the time React appears complex and hacky is because we tried to solve world hunger with one component. I've worked on plenty of React projects that were very easy to scale, modify and iterate because they focused so heavily on small independent stateless components.

    • > I know people love to make UIs stateless and functional. But they just aren’t. IMO UIs are fundamentally a bunch of state, graphically represented. So naturally all of the functional frameworks are full of escape hatches.

      Functional does not mean no state, just constraining state to inputs and outputs. Breaking that is a choice, and not good design.

      Elm, for example, provides all of that with one escape hatch: ports. It is really well-defined and that not fall into any of the impossibilities you mention.

    • > UIs are fundamentally a bunch of state

      React doesn't really contest that as-worded. It's just that, ideally, a nested component isn't the owner of important state.

  • I also have the same somewhat controversial opinion, the frontend community wasn't ready and (still isn't) to organise a functional codebase.

    The second problem is that React has a "draw the rest of the owl" mindset. Sure you have nice frontend components but now what about caching? data transfers? static rendering? bundle size & spliting? routing?

    • The reason for React’s “draw the rest of the owl” (which is a great way to describe it) mindset is that it’s born not as a framework but as a library, and to this day self-identifies as such. It by design tells you nothing about and is agnostic with respect to how you organise your code, where to put tests, what bundler to use, etc.

      IIRC React itself doesn’t even know anything about the Web or DOM, as that integration is supplied by the pluggable reconciler, which lives in a separate library (ReactDOM).

      One could argue that with the amount of batteries included perhaps it ought to undergo a grand status change, but until then it’s hard to blame on the authors of a library that they are not delivering a framework.

      5 replies →

    • Yeah, as a solo dev quite new to frontend, that made me nope out of React almost immediately. Having to choose a bunch of critically important third-party dependencies right out of the gate? With how much of a mess frontend deps seem to be in general? No thanks.

      I settled on Svelte with SvelteKit. Other than stumbling block that was the Svelte 4 -> 5 transition, it's been smooth sailing. Like I said, I'm new here in the frontend world and don't have much to judge by. But it's been such a relief to have most things simply included out of the box.

      5 replies →

> React is much more complex than the technology it's building on. Necessarily, to enable it's features

React, just like most software today, is excessively complex for the tasks it performs.

The only reason React is used is that many use it as a framework to attempt to provide more interactivity on the page without page reloads. There are other frameworks to do this, but none are as well-used.

Webpage interactivity with data was accomplished with page reloads via cgi-bin in the 1990s. Everything that has been done since then was not strictly necessary to produce the websites we use today; it would just be a more choppy experience.

A smoother experience didn’t require the overwhelming complexity that was introduced primarily in the 2010s in a framework war that React basically won. That complexity is the reason why many web and full-stack developers in the 2010s (such as myself) lost their minds and quit or seem incredibly depressed, grumpy, and confused much of the time today, and why some have invented strange new frameworks to attempt to reduce this complexity.

  • I'm just genuinely really confused by this take.

    It's a 100x easier to build products today than it was in the 1990's. (I don't think that's an exaggeration in the slightest)

    It would be basically be impossible to build anything like Maps, Excaidraw, Chat GPT etc.

    Arguably people are reaching for the tools without those interactive requirements ?

Is this the same with everything? In the past, a hard drive, a mouse, or a web camera was a dumb piece of hardware and a driver that ran on your PC. Now, IIUC, each of those has it's own computer (SoC) running an entire OS. Your phone probably has ~20+ SoC. One for USB, one for Wifi, One for Bluetooth, one for each of the 4 cameras, one for lidar, one for SSD, one for cellular, one for the secure enclave, one for audio, Each of them is an entire computer, more powerful than most 1980s general purpose computers, running an entire OS with multiple abstractions internally and all of that to make that device appear as yet another abstraction.

Am I wrong?

  • There is a difference between implementations getting more complicated vs. interfaces. It doesn’t matter if the mouse has a SoC if it still only exposes the same old USB HID protocol. The issue discussed in this thread is that the developer using the thing isn’t shielded from the increased implementation complexity and can’t just work with the abstraction.

React was built to satisfy the specific scaling and complexity needs of Facebook, and this CV-driven industry jumped on board with it pretending that what's good for Facebook is good for them. The incentives are completely misaligned: it's like nobody gains anything out of using the least amount of force and abstraction to solve a specific problem.

  • I did frontend before React, and it was a welcomed change. The core insight of UI being a function of state is a good one. It saves you a bunch of headaches from the jQuery days where you’d have multiple code paths per UI element (adding, removing, mutating). That said I think they lost the plot with hooks and things have gotten needlessly complex since then.

    • > The core insight of UI being a function of state is a good one.

      We had that before, it was called HATEOAS.

Managing state and syncing it to the DOM manually is much harder than React (or any other big framework) for any non-trivial web app. Reactive, inherently asynchronous, event driven applications get complex easily.

  • Right. I encourage young devs to build a complex app using vanilla js. Feel the pain of two way state management. Then you’ll gain an appreciation for react. And you’ll learn browser APIs and know when react is overkill because it has its own pain

    • i’ve tried this, and it almost almost works to just rebuild the Dom on every state change as a pure function of state without any react or anything. The resulting interface is actually way snappier than react – but preserving local state of elements like what text is highlighted, where the cursor is, which radio button is tabbed to etc turns into a nightmare.

      3 replies →

    • It's not even the young devs. It looks like most of those complaining are back end developers who "rarely tinker with frontend" but think they can teach everyone else how to make it simple because "it should be static forms".

      A great example of all-world-is-a-nail stance mixed with extreme hubris.

The problem is app-document impedence mismatch. CSS makes stuff easier but for doc-like pages. In addition doc-like pages want some app-like niceness too.

If you need to be an app you usually need a framework to stay sane (evidence: most other native UI kits are frameworks of some sort) and thus React etc. But they want full contol. Thus 2 ways to do a radio etc.