I lost track of it around maybe version 0.6, by the time I picked it up again we were in Redux land and the framework was five layers of crap deep. Sigh.
I lost track of it around maybe version 0.6, by the time I picked it up again we were in Redux land and the framework was five layers of crap deep. Sigh.
The most radical addition since the early days are functional components and hooks, which are not mandatory to use (class-based components are considered “legacy”, but aren’t actually deprecated). Another one is RSC, and you need to care about those even less (though they can come in handy in some scenarios).
Okay, there was one more somewhat significant change under the hood: in 0.14 they’ve made React more of a general-purpose library, splitting DOM-related specifics into ReactDOM. This separation can’t come without some overhead, so it’s unlikely React would ever going to be the most performant for the Web. (Last time I looked, Preact was faster—they did abandon that layering and went with the coupled architecture.) However, that didn’t magically turn React into a slow bloated framework—but it did enable a variety of interesting non-Web applications such as rendering native apps, rendering on embedded LCDs, etc., where you can use React core as a standalone renderer with your own reconciler instead of ReactDOM.
Once react switched from class based components and mixins, each subsequent release was only more confusing. I remember the conference talk where they explained the problems with mixins (forgetting to cleanup and them all sharing one state), both of which can be solved in a few different ways, but they opted for a whole rewrite for hooks, which I “get”, but think it increased the complexity dramatically for a very low gain.
That was marketing more than reality.
VDOM diffing isn’t the slowest way to update complex UIs but it isn’t the fastest either. In practice your app often ends up generating a lot of VDOM which then gets diffed away… a bunch of work and then a bunch more work to determine the first bunch can be thrown away. The app developer needs to step in to manage and optimize the process.
The primary initial benefit with React was an improvement in reliability. Our previous implementation (in Backbone IIRC) wasn’t doing it quite right. Having it built into React was a gamechanger. Then with judicious use of shouldComponentUpdate you could minimize the amount of VDOM thrashing required.
I know at one point we explored immutable.js to make the diffing super efficient but the DX was pretty bad. I’m excited for JS to get records and tuples at some point and make that all way simpler. But for now it feels like shouldComponentUpdate and PureComponent are a lost art of React, few do it.
Frontend development is not being enshittified. We have so many frameworks that you can switch to if React isn't your cup of tea. Hell, you can use Astro and use React, Vue, Svlete, etc and it renders to HTML. HTMX is a new framework and easy to pivot too since React devs know JSX.
React is also silently borrowing ideas from Svelte and Solid.js (and those were inspired from React) so all these frameworks are improving each other without even knowing it.
We're seeing the same with RSC. Many Next.js users are updating their apps to use the new App Router, but I've seen many just stick to the Pages Router since it just fucking works for their app and RSC has improvements, but none they care about.
I wonder if some of it is a perception issue: Everyone, including the instruction manuals, Stack Overflow, and search results, are talking less and less about the way I do things, and more about these new ways.
You can also try changing it from the inside, but it’s swimming against the current.
If you’re a decent engineer, learning a new library should be the boring part. It’s not like any of these libraries are introducing highly specific conceptual paradigms.
The average developer doesn’t get to choose at all. This liberty was taken away from them in the name of “easier maintenance”, a “larger community”, “stability” (ha) and other ill-informed platitudes. This became a self-reinforcing cycle when companies started hiring for React experience.
The cycle continues. People acting like the [current popular thing] is the problem are missing the forest for the trees.
The latter got a lot worse. Along with React came the rise of evangelists, celebrities and their courses and a generation of developers raised on the idea that github stars are the ultimate measure of software quality. The jQuery era was peaceful by comparison!
There’s nothing stopping me doing that on a solo project but frontend web dev is increasingly a monoculture around React so when you’re talking about making this decision in the workplace you end up using React whether it’s the right idea or not.
I worked at a place that ended up using React because a senior manager was concerned about hiring and wanted to use something we’d be able to easily hire for. It wasn’t actually a good tech fit but that wasn’t the priority. And in many ways he wasn’t wrong. There’s a mini-generation of developers that have only experienced front end development though the lens of React and have barely if ever used, say, raw CSS.
And that perfectly describes what is happening to frontend development.
> We have so many frameworks that you can switch to if React isn't your cup of tea.
Yes, that is what I was alluding to by calling it a "revolving cycle": Dominant Framework A is a bloated mess -> Framework B appears, it's lean and a joy to use -> Developers switch to Framework B, it becomes dominant -> Framework B gets enshittified into a bloated mess -> Framework C appears, it's lean and a joy to use
Happens everywhere in software, but in web frontend dev, it happens a lot more quickly.
but I admit something is off with react somehow (and i'm pretty favorable to it usually).
Before you know it, you've created a whole new paradigm that has it's own sets of new problems, even those solved by the original HTML/CSS/JS model.
But now it just feels so heavy and that the initial elegance has been lost to history entirely.
The amount of rope it gave to hang yourself. Hooks were the harbinger of the sad state that what was to come.
The OG React was a breath of fresh air because it introduced the world to immutable data flow. The component model was dead simple. You had a fat (for better or worse) class that served as a management point for your side-effects and IO, then a bunch of stateless transformation functions / components.
The old class + lifecycle methods imposed a much needed friction on the development process. Their clunkiness was a feature (imo). It raised the cost of creating stateful components / performing side-effects wherever you wanted.
Then hooks showed up. In a lot of ways, it feels like React is now rediscovering the bad parts of OOP: uncontrolled mutation and side-effects. "Immutable data flow" means very little when everything is launching side-effects, updating some global store, modifying 12 layers of caches, writing to local storage, etc. etc. etc. etc.
It became a complete nightmare to reason about what an application was actually doing. Most of my experience with React (at least as of a year ago) was debugging performance issues, or UI quirks from component A clobbering updates from component B, because some special GraphQL caching magic modifies some global cache somewhere in some provider, which is 37 layers removed from the code you're actually looking at.
As a stopgap, I just made a completely unstyled alternative to that internal admin dashboard that uses Handlebars HTML templating (no Javascript) on the server. Inclined me towards dependency rejection (which is an approach I was already taking for some side projects).
And anyone with any kind of software experience knew this was going to happen when hooks were announced. But the community bought it wholesale and dove in head first, so the rest of us were dragged begrudgingly along. I think it's been long enough now to resolutely say it was a bad idea and should have never been pushed the way it was.