Comment by ehnto
6 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.
> 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.
There is a Vue version as well.
Here it is: https://www.shadcn-vue.com/
I've started straight up being doubtful of every UI kit until I see in the docs a HTML or non-React example.
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.
Obligatory "you should try Svelte"
1 reply →
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.
So is a span or div element? What am I missing here?
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.
The problem is also that every other year contracts/paradigms/... are broken, introducing bugs in libraries and documentation.
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 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?
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.
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/).
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
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.
> 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 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.
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.
4 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 ?
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.
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.
I've seen React components where div is used with click event for adding a normal link
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.
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.
Worse still is the misunderstanding that React is simple. It’s an endless stream of cache invalidation bugs. Linters are getting better at catching these. But they also have false positives.
What is cache in this context? useState? What do you mean by cache invalidation in react apps?
Stale closures, perhaps.
2 replies →
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.