Oh, and the author would like to kindly point out that React is legacy now. Because they said so. In case you didn't know.
With a topping of how this is all just solved by "giving a toss about the user", followed by a cloying apology for being vulgar
I'm not in web and am amenable to a good web dev hot take but this simply isn't worth the time, it's an array of generic wisdom delivered as if it's specific, written with the effort of someone who is proud of themselves when you disagree.
I was not able to notice any difference between them
I don't get what the point of these comments is ? If you're using RPI with a 2g connection you'll have a bad experience shopping at the site ? And somehow that's supposed to factor in to my tech stack decisions ?
Software engineers tend not to experience the web on the same class of device as most of their users.
It's a fair point to note devs and users might have different devices, but in some cases they don't and the decision to use React might be well-founded with that fact.
I find it extremely odd that this was even a question on this site. Do you think the problem you’re solving should impact your tech stack at all, or is your tech stack more important than the problem?
Note most of this is nonsensical too.
His primary thing is "you don't need client side code because JS = (HTML + CSS) * x, where X >= 1"
We can start sneering about not caring about users there, too, having a one time client side download of that magnitude can certainly be much better on the poors than 10 page loads with SSR.
I have a newer iPhone and Safari is still full-refreshing pages constantly due to memory.
With utmost respect, that's not what I'm saying :)
I hold no hot take position on anything web dev, or any firm declarative position.
What I'm trying to get at is, indicia of an article being half-baked includes things like asserting all that's required to agree is to care about the user.
This feels good to say, but doesn't say anything, other than there's been at least some short-circuiting of thought. We can come up with many trivial cases where "caring about users" involves requiring client-side logic during rendering.
And there's also the other side: people who insist in overusing React. Perhaps that's what the author refers to.
I for one have see HTMX eat React for breakfast in a few of my clients during consulting.
If you struggle with backend code then you’re just not a good backend developer. Maybe just stick to HTML/CSS.
i don't know about all that, but this is an incredibly tired diatribe.
> Perhaps that's what the author refers to.
they are clearly not.
"In short, nobody should start a new project in the 2020s based on React. Full stop."
What about the rest of them?
that is neither here nor there. you are replying to an article whose thrust is that react ought never be used.
> Somewhere that’s actually an application might
might, lol? wait are you the author?
> most line of business applications would be better as something like Rails views rather than React
why?
In most cases later frameworks are slow and bulky. I certainly hate using sites like X or Target on mobile. Random delayed loading of things, loss of scrolling position when going back, things just not loading the first time it delayed reactions. It sucks.
This is how you end up with an amalgam of legacy crap that no one wants to touch. I can’t read guarantee you that outside of big tech and a couple of unicorns started by experienced devs this will NEVER work reliably.
eg React Native is dismissed in 5 sentences, with no real solution at all given to the basic problem of wanting to have a website and mobile apps without writing your app 3 times. Let alone a website + mobile apps + windows + mac clients. The suggested solutions do not address this need -- eg there's some Apache crap that no one I've heard of uses (it's renamed Adobe Phonegap crap that Adobe bailed on and tossed over to Apache); some random link to a 5 year old google i/o presentation; etc.
As far as I know, there's basically 3 toolkits that offer this: React + derivates; Rails with Hotwire; and Flutter, which means trusting Google (fools only), and which has recently deprioritized desktop... so that's a rock solid foundation to pour millions of dollars of eng time into. And I guess Xamarin, if anyone is using that.
As for the article, honesty probably would have just had the author write something like: "RN: an unfortunate but maybe your best choice in these circumstances" instead of pretending there's serious alternatives eg the Apache garbage dump.
The ecosystem is another aspect. You have so many great options for off the shelf components and libraries with React that you might not have with other frameworks.
Before anyone mentions Custom Elements and Web Components, I must say I tried it. Gave it a lot of effort to be a solution but it is not!
That's covered in this section: https://infrequently.org/2024/11/if-not-react-then-what/#%22...
"The ecosystem is another aspect. You have so many great options for off the shelf components and libraries with React that you might not have with other frameworks."
That's covered here: https://infrequently.org/2024/11/if-not-react-then-what/#%22...
https://github.com/brillout/awesome-react-components
This point is not directly covered in the article.
It is one of more clear examples of a framework:
- calls your code
- heavily affects how the code is written
- requires significant build configuration (could even be argued it is something more than a framework, but definitely not a library)
A library does not impose any configuration. I don’t see any required configuration with React. You can use it wherever you want in your code as an addition.
My piece on that: https://datacadamia.com/code/design/library_vs_framework
It isn't? I find React to be great to work with.
Most importantly, it’s also not particularly performant on the client side in real-world scenarios.
For evidence, here’s a guy testing major websites using his awesome react-scan tool: https://x.com/aidenybai/status/1861442057598062653
I think last year an Amazon frontend engineer wrote some tweets explaining they tried React and it was too slow. So they keep using Java for SSR and sprinkle vanilla JS. They were still using jQuery until a couple of years ago and probably still are in some parts of their site.
Someone is contesting that "frameworkism isn't delivering" when we have objective data to prove that it is in fact not delivering.
The Amazon store is just a good example because there's a lot of data about it, not because it's FAANG.
Please help me understand where I misunderstand
"No, trucks are good for X"
"Look at this use case (Amazon) with tons of objective data that shows that trucks are bad for X"
Are you arguing that web devs should ignore CWV for e-commerce sites?
The Amazon site is pretty ugly, yes, but it’s functional and fast.
But there's no inherent reason React couldn't be used for a page that basically shows pictures of products with a description next to them, the bottlenecks will have nothing to do with the frontend in a well engineered system for that type of site
Even freaking Google (who really should know better) suffers from that. Amazon's retail frontend uses plain HTML, so it works fine.
It's way too easy to put some state information into the context and then have your pages depend on it. For example, you have a page with a filter that is implemented via a simple state, and then a list of widgets that pass the filter. The widgets have a click handler that opens the widget details.
Now you right click on it. If you're lucky, it opens the widget details in a separate tab. However, the filter information is lost.
^ These two statements are at odds with each other.
React will return a pure browser link that behaves exactly as a browser link:
function Comp() { return <a href="some-link">text</a>; }
> The widgets have a click handler that opens the widget details.
>
> Now you right click on it. If you're lucky, it opens the widget details in a separate tab. However, the filter information is lost.So, the problem isn't React. The problem is people overriding default browser behaviour for their widgets. It was a problem before React, and it will be a problem long after React.
For example, here's Google's premier site about web technologies: https://web.dev/articles Check out the pagination links at the bottom. There's no React on the page
No it doesn't (in practice). React is typically used with something like React Router that takes over the whole sub-tree of paths. So links are handled by the single-page app itself, and this can lead to the state leaking through.
Yes, you don't _have_ to do it this way.
Yes , yes it does, in practice.
> React is typically used with something like React Router that takes over the whole sub-tree of paths. So links are handled by the single-page app itself,
"Taken over by Router", "handled by SPA itself" .... "React is to blame"
> Yes, you don't _have_ to do it this way.
Yes, you don't have to it this way, and this isn't React-specific. See Google's web.dev site built with web components
Links work fine, out of the box, react treats them the same way vanilla js does. JavaScript onClick events aren't links, and that's true whether you're using react or vanilla js.
> It's way too easy to put some state information into the context and then have your pages depend on it.
What do you mean it's too easy? If someone makes poor engineering choices because that's the "easy" thing to do, that's their fault, the tool didn't make them do that.
> Now you right click on it. If you're lucky, it opens the widget details in a separate tab. However, the filter information is lost.
This is true of JavaScript in general, it has nothing to do with react. In order for links to work, the server has to render pages that correspond to the link, whether that means encoding state in the url or pulling it from a session, this is required whether you're using react or literally anything else.
Just like how routing and history is “solved” but I encounter websites every other day that completely break my browser history.
I don't think that's true. More likely, you use react websites all the time and don't even think about it because the links work as you expect.
I worry that most people complaining here about React, including the OP, do not actually understand the very basics of React. Here someone is complaining about how React somehow messes with deep links. Without understanding that React does nothing to links. Nothing.
I'm discussing the retail site specifically because that's where CWV matter.
If a company has internal tools that take seconds to load it doesn't really matter. Captive users don't have much of a choice.
E-commerce is fundamentally small data once the user lands on a product page, so every subsequent link and click should be instant.
The only point I can agree with is that React is stupidly hard to learn. It feels like a tool made for aliens, though once you master it, it can be pretty efficient.
Sorry to be the bearer of bad news, but the JS-free web isn't coming back. And if you're using modern JS, you might as well use React (or a similar tool). The user won't be able to tell the difference.
Hard disagree. Hooks are 100% what is best about React these days and custom hooks make organizing or encapsulating and sharing behaviors between components a total breeze.
This is one of the reasons I think hooks stink. It seems like they tried so hard to avoid using classes that they came up with an opaque, framework-only way to manage state so that they could declare "ha! Stateless functions at last!". The state's still there, it's always gonna be there, it's just now hidden behind an abstraction that has a few footguns.
2. Sorry but if you keep using "weird", "hard" and "complicated" adjectives to define something that is quite honestly not so hard to grasp you make it hard to not go with "skill issues".
I’m using weird and hard in a relative and not absolute way. Weird because functions can’t have state, and for years we’ve been taught to keep functions small and predictable. Hard because there are much simpler ways to write stateful code other than hooks. The problem with react is that instead of creating a powerful state library, powerful ui library, and creating a bridge between them, they chose to subjugate the state library to the UI library’s limitations.
For example, `api.fetchInfo()` would want to feed Loading | Success(T) | Error(E) back into the React component call-site when they change.
EventEmitters come to mind but aren't without their own issues like subscription leaks. And you have to track component arguments in order to know when to call the service again when they change which is a classic source of complexity.
Hooks provide a solution for this since they themselves are just nested React lifecycle constructs (like useState + useEffect).
Of course, the class component solution to this was to use an HOC, but that had its own issues like complex data flow and wrapper hell.
Hooks solve problems of composition without Yet Another Wrapper and they give clearer data flow, better ref forwarding, etc.
It's easy to see complicated useEffect spam and blame hooks but frankly that wasn't any better when it was happening at different layers of HOCs.
1. you can still write class based components if you want, but if you are in a team everyone will hate you for that because... 2. the preferred and vastly more flexible and powerful way is functional components. That's it, there isn't any other way or any other mystical layer of magic.
What everybody in this umpteenth omfg-react-is-satan thread is that implementing complex things with simple things is a fucking pipe dream. Fucking deal with it.
"Fucking deal with it?" What are you, a cultist? I answered a question here, fuck off.
https://overreacted.io/making-setinterval-declarative-with-r...
It has never went anywhere? All it takes is a user brave enough to disable it or to use a web browser that doesn't use it or has issues with it. But for some reason many web devs actively ignore that.
However, I think any new paradigm is difficult starting out. Recently I've been learning OO for work and I've been finding it stupidly hard and entirely unintuitive.
It feels like a clever proof of concept with a leaky abstraction at its core, one that no amount of effort can truly fix, no matter how much they throw at it. They’re even building their own compiler. A compiler. For something that’s supposed to represent the V in MVC.
As a SPA framework, it’s questionable. But using React to build server-side apps? That’s beyond absurd for me, it’s like Electron for the backend, only worse. And yet, the industry loves to pretend otherwise, so here we are.
Why people are so keen on stabbing themselves just because there's one or two weird shaped forks in the kitchen drawer. Why do suddenly everyone tries to use it for spreading butter or peeling eggs?
Just understand what unidirectional data flow is and you are golden. You know the entirety of React you should be using for your first year of full-time job.
As for your question, “Why does everyone suddenly try to use it for spreading butter or peeling eggs?”
I guess part of the reason is that many people rely on older tutorials and patterns where the usage of useEffect was much more tolerated or even encouraged as a catch-all solution. There’s still a lot of inertia from the old componentDidThis/componentDidThat paradigm, with useEffect being its direct replacement.
I feel it is only a recent tendency to finally abandon the overuse of effect hooks.
Just open an average Stack Overflow React question, and you’ll see how many useEffects are crammed in there.
It was so easy that people strived very, very hard to make it seem complicated - and they succeeded. Back in the day every React tutorial layered in soooooo much other stuff, Redux and a million middleware layers that completely obscured what React was.
The core of React though is really simple and no amount of attempts at complexification can destroy that.
Hooks is really one of those things where you need an IDE to tell you that you’re doing it wrong, since there’s a whole bunch of footguns. It’s doing its best to solve a hard problem inside the limitations of JavaScript, but it is essentially a kludge.
Just like in Flex the difficulty (and don't get en wrong often extreme awful difficulty) comes when someone fights against the system and can cause a cascade of terribleness. There were always telltale red flags when looking at Flex code when someone tried to circumvent the component lifecycle and the same smell can be spotted in React code.
Would it be fair to say in which case that React shouldn't be a tool teams reach for unless they have people who have mastery of it or can pay for it?
> user won't be able to tell the difference.
I think the user can:
Correct. The reason is not the frameworks but the languages. What is needed is a much more high-level and feature-powerful language.
Just look at react. Passing down dependencies/values is a pain. So what did react do? It introduced contexts. Similar, other react addons try to solve this problem. But they all sacrifice type-safety in the process.
They simply cannot solve this problem; only a better language can. Typescript maybe could, but they restrict themselves to not generate code (or at least very limited, I think for enums they do it).
Without a change here, nothing can ever improve.
There is absolutely nothing preventing you from keeping those safety - I’m not sure what you mean by that.
The typescript type system is very advanced, maybe even too advanced! I disagree that more sophisticated languages are required.
React won because it solved a real pain point for a group of people, using the techniques they were already using... but better!
Having built large apps in angular, handlebars, and jquery... it was (and still is) a godsend for building highly interactive, stateful web applications.
I am deeply skeptical of some of the stuff that people are doing now wrt. putting backend logic into React components, but the fundamentals of React are still very reasonable to me.
I build all my react this way.
No prop drilling, no Redux, no context, no mobx no state.
If you need to communicate between components then send a document event.
Your react application will be dramatically more simple without state.
React is reported to be used by 39.5% of developers worldwide, while Vue.js is at 15.4%. The number of "apps" using just HTML+CSS is precisely zero, because those aren't "apps" they're documents.
React holds an important space but its hardly the only tool that can succeed in a "large project with lots of screen updates and state changes". That's ridiculous.
My main point was to compare "frameworks" v.s. "no frameworks", rather than to say that React is best, but if you want my opinion then yes I do say React is indeed the best, and I admit it's an opinion not a fact. lol.
1. to birdlime
2. (reflexive) to get bogged down
maybe you would expand on this? I have no intention to challenge you, just genuinely curios if and why I should consider vue over agnular for new project (I use angular already).
SO trends show that angular is more popular, while vue is loosing share (not necessary absolute number): https://trends.stackoverflow.co/?tags=angular,vue.js,reactjs
However I think the "drop off" in the chart for React is misleading/incorrect, and likely indicates just a slowing down of the economy and/or people moving to LLMs for their searches and abandoning StackOverflow completely, as I have.
For the past year I haven't yet found a question that an LLM couldn't answer better than S.O. could, although ironically most of the LLM learning did come from S.O.
Anyway, yeah shops will stick to their legacy code forever unless something forces change, because retooling is super expensive in money and time, not to mention replacing all your developers with different ones!
IMO right now it’s easier to start an angular project with much less foot guns than react.
What I mean by dead is it's a VERY unlikely choice for any new app. People will choose React or Vue most of the time. You don't see Angular used hardly ever for a new project.
BTW: Vite is the new best way to manage the build pipeline, and makes React super easy to start using.
Fortran certainly has its issues with portability and feature development, but it is by no means dead.
And your drill press example is agreeing with me, which is that, as I also already said myself, no one needs to have ever used something to be able to declare it dead, nor did I declare something dead because I don't personally use it. That's absurd.
https://developer.chrome.com/docs/web-platform/view-transiti...
Yeah, but it ain't. lol.
Users don't care how it was implemented or how nice the code looks, they just want it to work.
By your measure though, it sounds as though you'd be fine if these page loads in the javascriptless world were done in iframes, since then only some portion of the site is being reloaded?
I'm using that to illustrate the argument is absurd and the basis on which it is made seems also absurd.
SPAs are heavy and frequently written poorly, often eschewing the principles of loading only the bare minimum for a kitchen-sink approach. If you view the web as having only those two options to accomplish "real work" then yeah, you're gonna thing that SPAs are the only way. It's not reality though.
In my experience, these apps are rare, yet SPAs are prevalent. Which is a problem.
It would be nice, from a user perspective, if boring "apps" that are mainly forms and tables would quit it with SPAs already.
Making an entire application a single page load and then some API calls sounds attractive when your application is small to medium sized in terms of complexity. It runs into problems when complexity or feature count pass a certain point.
However the reason my Dialog Boxes open in a millisecond, and close in a millisecond too, is because I choose to render them locally. I'm not against SSR tho, as a viable concept. That's a different complex discussion where there are trade-offs to consider.
The options you present are: "either use a JS framework or don't use JavaScript at all". That's a false dichotomy. I've built plenty of interactive apps with JavaScript without using frameworks.
And once you reach sufficient project complexity, you will end up with just another homegrown framework, with all the lessons learned by mature frameworks, left to be fixed over the next 5 years.
Yes it is. App.js is all the code there is. You can't count the two other files with 10 lines each. lol. Let's be honest here.
And yeah for a tiny toy project like this you can get away with having zero design, zero architecture, zero object models, zero classes, and sure since everything is zero, we can throw in "Zero TypeScript" and "Zero Frameworks". Looks like some high-schooler's first ever coding project.
No, it's not. Chatbot.js is 3400 LOC.
There's literally only 4 JS files in the whole repo and you couldn't be bothered to check how much code they have? Even after I told the other guy who made the same false claim "no, it's not a single file codebase"?
Jesus you people are insufferable. So obnoxiously confident while being wrong about easily verifiable facts.
> tiny toy project
Huh? 99% of web development is about rendering text and images. This project is moving your mouse inside a web browser & provides a plausible chat experience without a language model. That's more ambitious than just about any actual work project I've seen.
What people are saying is that for LARGE projects you NEED a framework. And your app is tiny. It's got like two source files. So it's just an example of a tiny project getting by without a framework. I have a couple of those currently myself, because I don't need a framework for them. They're just HTML+CSS+JS.
https://news.ycombinator.com/item?id=42282054
"brochure-ware"
B-R-O-C-H-U-R-E-W-A-R-E
I was willing to assume good intentions from you earlier, but at this point it's clear you're just lying. You've seen the number of files in the repository, we already had a back and forth and you already conceded there was more than one file. And yet here you are, reiterating the same lie. Weird stuff.
If the same app had been written by a typical team of React devs, it would be >1000 source files and 50K LoC. That's not an argument against my approach, it's an argument in favor of it.
a codebase with a 1300 line file.
I mean if I need to change a variable name in a class or something, unless it's a perfectly unique name (easily searchable), it would take me hours to do in JS what I can do in 4 seconds with TypeScript.
The claim upthread was that you couldn't make a web app at all without a framework ("or it would just be a document"). I said yes you can and the goalposts shifted to: sure, but only "brochure-ware" (referring to simple unambitious projects). I show an ambitious interactive project made without a framework and now the goalposts are moving to: sure, but large distributed teams couldn't work like this? You know, this solo project is more ambitious than 99% of the projects I work on at my actual work. You know, projects that have 10, 40, or 100 devs working on it.
Sure you can develop very large projects in JS, as long as you don't mind being 1% as efficient, and having 100x more bugs. In JS, refactoring a huge project is the biggest nightmare in the world and really no human is capable of doing a great job of it in a reasonable time, even if they have a high IQ and decades of experience.
Any language that lacks type-safety is completely inappropriate for large-scale projects. There's no seasoned developer on the planet who disagrees with that sentiment. None. Zilch. If some guy claims to be #1) decades experienced and #2) doesn't like type-safe languages, then he's lying about either #1 or #2 or both.
But there are some things that are obvious to any seasoned developer and the value of type-safety is one of them. It's not my opinion. Is a fact. And yes if you say you have 10+ yrs and you don't prefer type-safe languages, then yes I indeed do not even believe you.
Have you heard of Python by any chance? Pretty much the entire field of data science is built on top of a dynamically typed language. Plenty more seasoned developers working in that field.
If Python was just fine without type-safety that's how everyone would have kept it.
This is another lie from you. A vanishingly small minority of Python developers is using "every type-safety feature available to them". Not that it even matters to your earlier claim, because Python is not a type-safe language even for those developers who are using "every type-safety feature available to them". You claimed earlier that "Any language that lacks type-safety is completely inappropriate for large-scale projects" even though you seem to be aware of the fact that "seasoned developers" are using Python for "large-scale projects". So, again, you're just lying.
Python developers simply tolerate the lack of type-safety only because it's a trade-off to get other things the language has to offer. I agree there are trade-off decisions being made.
> For any large project you need type-safe languages. 99% of experience developers (10+ years of experience) will agree with this opinion.
Clearly, more than 1% of experienced developers choose Python, despite it not being a type-safe language.
You don't believe what exactly? Don't believe I have 10+ yrs of experience? You can see that my GitHub account has activity from the past 10 years, so... you don't believe I prefer dynamic typed languages like Python? You think I actually prefer static typing and I'm lying about that? Like what?
Oh, and it just so happens that Python was the most popular language in the 2024 StackOverflow survey: https://survey.stackoverflow.co/2024/technology#2-programmin...
I guess literally none of those people were "seasoned developers" either, and none of them had ever worked in a "scaled" and "large" project, like you mr big man.
Me: "Seat belts are important."
You: "Awfully funny considering our major car accidents these days are mostly all ones with seat belts."
You're implying a nonsensical causation that's purely a correlation.
If appeals to the status quo were reasonable arguments, there would be no room to improve on what is.
The more popular a piece of software is, the more likely it is to have had the bugs worked out of it, the more people there are reporting issues, the more answers there are on StackOverflow, the more likely AI/LLMs are to be able to answer questions, the more secure it's likely to be, the more stuff interoperates with it, etc. Popularity alone isn't a good reason to select something, but it's a good data point, with which so judge viability.
Good thing we’re mostly keeping the attitude to hobby projects.
Can’t imagine hundreds of artisans™ bikeshedding over what the hell this even means.
And I can’t read with a straight face an article talking about complexity of React while suggesting Vue (sic!) as an alternative. Lol!
Most of the people commenting on this piece won't have read this whole article (it's long, and internet attention spans are short). As a result, you'll find plenty of the comments here were exactly predicted by his writing.
I see him as something of a Cassandra at this point, doomed to see the truth about web performance based on many years of research... and then to have nobody believe him. https://en.wikipedia.org/wiki/Cassandra
> In short, nobody should start a new project in the 2020s based on React. Full stop.
Good arguments here but the dogma doesn't help.
In my experience, regardless of your skill at communication, coworkers or bosses that are actually interested in getting to deep knowledge or detailed analysis about anything are extremely rare. If you need to communicate a subtle point or detailed argument, then you’ve already lost. This is because for any technical decision the opposite argument from FUD is easier to make and easier to digest, regardless of whether the FUD advice is to stay/defect on the tech stack or the design decision or whatever. IOW the winning strategy is basically to always go 2nd after what TFA calls the “thoughtful engineer” burns out the audience by being rational and thorough. Even more bluntly.. most people are just showing up to work and have no interest (and much less passion) for craftsmanship.
I wish it was different, since I believe in architecture / design. But, there’s a good chance no one cares about your detailed analysis at all and you’re much better off producing more shallow demos/diagrams/decks regardless of whether your audience is engineers or management.
My only quibble is that it’s certainly possible to choose React (or any popular solution to a problem) without considering other options too much, and still care about craft.
I agree! In general, people are resistant to change, period. Some are particularly wary of facts and logic (see: politics). Successfully getting points across, even when one "is right," often requires a lot of strategizing and non-technical effort.
Whole books have been written on this subject [1]. For those attempting to navigate the challenge, just remember that it's all too easy to burn out in the office while "chasing your ideals.". Doing this while keeping your sanity is an art :-).
--
1: https://pragprog.com/titles/trevan/driving-technical-change/
(non-wrapping extra long lines have not helped but maybe that's on my user agent)
My rules of thumb:
* informational website / blog - static frontend (Django! :heart:)
* some interactivity - htmx
* a lot of interactivity (app that happens to libe in the browser) - spa (React and weep)
For a very strong assertion he makes (even if you need spa, react is obsolete), he dismisses finding a good alternative as an exercise to the reader. The ones listed offhandedly in a side note look all the same (as react) to me.
The sad part is that it's the same increasingly hostile arguments he's making while he spent the decade making sure that browsers remain bloated and tech requires Javascript to even barely function: see his entire work on web components.
> I see him as something of a Cassandra at this point, doomed to see the truth about web performance based on many years of research
He's not the only one speaking about web performance, or doing research. He's not Casaandra. At best, he's a false prophet.
His series on web performance gaps is good, though.
I'm confused by this characterization of web components. While they can minimally work without JS now (i.e., declarative shadow DOM), the whole premise builds atop of how the web and the browser works, and that is progressive enhancement. Your browser starts showing you the content before all of the content has finished downloading, and as it finishes, it progressively enhances the content of the page. Web components is a part of that story.
Why do you want web components to work without JS? Do you also put the same constraints on frameworks?
Of course not. They need Javascript to participate in forms (though a button on WCs still can't work as a submit button), they need JS to handle global styles, they need JS to handle ARIA (there are at least two different proposals for this), they need JS to fix text selection etc. etc.
Nothing in web components two dozen specs builds on top of basic browser functionality.
> Why do you want web components to work without JS? Do you also put the same constraints on frameworks?
That's bot what I wrote. I'm calling Alex Russel's hypocrisy. He's ranting against web frameworks while he's spent the past decade creating tech that needs more and more JS for basic functionality (and more JS to fix issues previous designs and patches) and is literally advised to be used as only through libraries and frameworks
> In practice, the only thing that makes web experiences good is caring about the user experience — specifically, the experience of folks at the margins. Technologies come and go, but what always makes the difference is giving a toss about the user.
> In less vulgar terms, the struggle is to convince managers and tech leads that they need to start with user needs. Or as Public Digital puts it, "design for user needs, not organisational convenience"
This is the most important thing. The entire article series is making this point in great detail, and also being very angry at orgs (especially public services!) that don't get this.
I think this message does get a bit buried under invective against React. Surprise surprise, if you do start with user needs, then sometimes that does lead to you building a React-based SPA. I think from Alex's perspective working with organisations, looking at it from the other direction: for any given React SPA, it is unlikely that React was chosen because of user needs.
I get why people are offended or find it unhelpful. If you read through his Reckoning series, I hope you'll understand some of the righteous anger he has for organisations that fail to serve the user, even when public service is their explicit purpose.
Blaming it on React may not be the most effective strategy. Who knows. But I still find value in the message.
"In short, nobody should start a new project in the 2020s based on React. Full stop."
He lost me. My React web app of medium complexity is statically exported and gets cached by the user's browser. All the data it needs for the main page is fetched by a single graphql call. The UI code renders in less than 10ms even on old machines. Network and the backend are the primary bottlenecks for me.
Could I redesign and rearchitect it such that the frontend is very slow to render even on modern machines? Yes, quite easily. And I suspect, many people complaining about React's performance are doing just that.
Things that generate html on the server side need to pay for the higher bandwidth costs that are hard to cache well.
In the other hand with spa, a well configured cdn can have a short ttl on index.html and cache the unique per deployment js bundles forever.
The only server bandwidth cost is the actual api data
Re-Render the full page server side, app takes response, applies only the changes needed. Preserves scrolling state, etc.
Super simple pattern for building dynamic sites.
It achieves 95% of the effect, and you maintain one implementation, not two.
I think many people would argue that it is easier to build a good web app in React than plain HTML/CSS/JS.
The React API is way nicer to construct DOM trees than using Fragments, creating and appending children elements, concatenating strings to produce HTML, etc.
Imagine being able to do this without importing any 3rd party code:
const content = html`<h1 id=hello>Hello world!</h1>`; // New API: html Tagged templates [1].
console.log(content);
// Outputs: { type: 'h1', props: { id: 'hello' }, children: ['Hello world!'] }
document.querySelector("#container").patch(content); // New API: HTMLElement.patch.
I'm sure there are a few more details involved but it sounds like a relatively small addition to the current DOM APIs.I’m not aware of any initiatives like this currently. WebComponents could also benefit, as building a DOM tree within a class extending HTMLElement is still cumbersome: the WebComponents API doesn't really add anything to simplify DOM handling, which is why libraries like Lit exist.
--
1: Inspired by https://github.com/developit/htm
The critique seems focused on SPA architectures heavily based on React, as seen in frameworks like Next.js and Remix. To be clear, I also lean away from that style of web application architecture, but I’m not sure this 20-page article effectively makes the case for simpler alternatives.
After the initial "SPA fever" died down, these frameworks cropped up to address the shortcomings of SPAs such as a lack of SEO-compatibility.
Since the term SSR has been... "repurposed" now, what I was talking about a simpler CGI-style approach—no JavaScript, no async complications like Suspense. Rendering React components server-side often requires special tricks, especially when components interact with DOM APIs or make HTTP calls.
As an example, Templ has a detailed guide on using React in a traditional architecture without server-side rendering React components [1].
---
1: https://templ.guide/syntax-and-usage/using-react-with-templ/
const content = document.createTemplate(`tagged string`).content
You can already effectively do this, though you'll have to decide for yourself if putting the following lines of code into a top-level module translates to "Writing your own framework": function html(markup) {
const templateNode = document.createElement(markup)
templateNode.innerHTML = markup
return templateNode.content
}
Then your code becomes roughly: import html from "MyModule"
const content = html`<h1 id=hello>Hello world!</h1>`; // No New API Needed
document.querySelector("#container").replaceChildren(content.childNodes)
You're losing the pretty printing in the console but there's options for that -- from tweaking the toString() prototype method to straight up creating a custom class that acts as an Element.Worth noting too: you could cheat in the html function above and have it directly return content.childNodes, thus reducing the differences between the two examples to simply "patch" vs "replaceChildren".
In your example, are you envisioning that HTMLElement.patch() is doing something different than Element.replaceChildren() or Element.replaceWith()? That'd be one area that wouldn't be addressed with this.
Having it first-party would be lovely but it's already pretty doable.
Regarding patch, morphdom explains very well the difference between replacing and patching the DOM [1]:
> Replacing an entire DOM tree is fast but loses internal state (e.g., scroll positions, input carets, CSS transitions). Instead, we aim to transform the existing DOM tree to match the new one, minimizing changes and preserving state.
Also, there's the matter of performance. Diffing and patching as a single method call implemented natively should be a lot faster than using a bunch of JS code.
---
I suspect there would be a lot of edge case footguns in trying to write something like patch() that tries to crawl the content as a diff and make only the minimal changes. Things like events being bound incorrectly to elements, what to do when the structures of the old and new don't match in some breaking way, etc.
Not saying it can't be done but I suspect it's more complexity than we think of typically when using a term like patch. Some of those items (such as transitions) can be pretty straightforward to deal with already.
> Also, there's the matter of performance. Diffing and patching as a single method call implemented natively should be a lot faster than using a bunch of JS code.
Performance and the DOM (especially as typically deployed in an SPA / the "modern" web) don't really go together already, so I'm not convinced that's a particularly compelling argument. Making it first-party on its own is already that compelling argument IMO.
I personally wouldn't choose it for new projects, and I consider it essentially a brilliant research language (it's inspired a LOT of other UI work).
0: https://elmcraft.org/lore/elm-core-development/
1: https://podcasts.apple.com/us/podcast/elm-the-future-of-open...
2: https://reasonableapproximation.net/2024/11/02/elm-community...
I think react native is always a better choice than tools like cordova while the best choice is native development. every time i use a cordova app it is painful and you just know something is off. react-native apps are a lot nearer to native experience. you can differ them if your really trying to though. but if your just want a good native ios and android app react-native is a good choice. and you can slowly learn native development from there and shift to native if you like.
Use something like Leptos and be happy:
Sure the tricycle had streamers on the handlebars and the little basket on the front was cute, but you can get more places with a mountain bike.
https://krausest.github.io/js-framework-benchmark/current.ht...
And any high performance functions you need on the front end will be higher performance than JavaScript. Like bloom filters for example: https://nuenki.app/blog/bloom_filters_optimisation
Only in further updates to the DOM. There are very few use cases where you need to continually update thousands of DOM elements.
For most use cases, start up time and memory usage are really the most important metric.
As a disclaimer, I still prefer vanilla JS and progressive enhancement.
The other point isn't so much that there's a wrapper around the DOM, but that the DOM API itself is bad and slow. There's only so much pain a better language can take away here, and Rust isn't even a better language for that domain.
But it's JavaScript glue code generated by Rust's wasm-bindgen that you don't need to care about. And eventually the glue code will be unnecessary with wasm component model DOM access.
This has felt increasingly untrue recently. I hope I'm just experiencing the peak of the bell curve but I've been bumping into more and more devs who only have experience in SPA React and associated styling frameworks. Ask them to actually style something and they flake out.
I was used to some tribalism in backends (everyone thinks theirs in the best and equally hates PHP devs and Wordpress) but can all publish a static page if asked.
It's a self fulfilling issue. Mid-managers want React because Facebook and pre-juniors train to meet job postings. Not enough question it.
Big money FAANG posts have really distilled the market down.
Maybe I'm just an oldfart. When I started a quarter of a century ago, people were crowing about Frontpage experience. I'm fairly sure I'd boasted about Macromedia Dreamweaver 3 expertise. And there was an explosion of technologies being thrown around between different devs. But now you don't get to discriminate against bad technology if the market demands it.
It's pretty common to not want the default behavior of an A tag, so instead of the e.preventDefault(); e.stopImmediatePropagation(); dance, a clickable div works great. Non deep-linked sub-nav (tabs, etc...) come to mind.
Or maybe I'm hooked into a router and I need to pass some additional state, or control a transition direction, or maybe I want a navigation to happen after some async action completes, etc...
Also, not all clicks are navigation actions.
BTW, I'm not a react guy, just vanilla web components here, but genuinely curious why you see clickable divs as a bad thing?
* It often (always?) breaks middle-clicking/opening in a new tab. In your navigation example is fine, but for example in Jira it's an absolute crapshoot which links will behave properly when middle-clicked
* We already have a tag for a clickable element that is not a link: <button>
> Accessibility tools
Not all applications are created for accessibility, it depends on the app and the intended audience. While in a perfect world we'd all be section 508 compliant, cash strapped startups frequently aren't in a position to invest in that for MVP.
> It often ... breaks middle-clicking
Do you use the same standard for a native app that you install from an app store? Almost everything I've written over the past decade or so has been "web tech as a replacement for native" - not a public web site, so the function comparison should be against native apps. I probably should have mentioned that in my original question.
> We already have a tag for a clickable element that is not a link: <button>
Sure, but I don't think it always makes sense semantically or from a code standpoint to use the button tag. For example, maybe I have a tiny little plus symbol for "expand". Like a lot of folks, I generally use some like font icons, or material symbols for stuff like that. Frequently it makes more sense to use a span or div to render the icon, and just handle the click event.
I'm not advocating for the use of divs instead of "a" tags everywhere, I just think there are normal and reasonable situations where it makes sense.
All engineering is a series of compromises and trade-offs. I'm not going to judge a dev that makes an info icon work to slide out a drawer which has a tabbed sub-nav, because they didn't hammer an A tag into something that it wasn't intended for, or because they didn't want to try to make whatever font icon library they're using work with a button tag.
Just use <a> and you don't have to.
If you're linking to something, then just use a link. So people get their accessibility/screenreader support, and you can still use JS to accomplish whatever other auxillary behavior you want.
href="?tab=tabName"
> need to pass some additional state href="?state=stateId"
> or control a transition direction href={condition ? "/direction/a" : "/direction/b"}
> maybe I want a navigation to happen after some async action completesSmells like a mistake. Or a button.
> Also, not all clicks are navigation actions.
There are other interactive elements like buttons.
• A large portion of the cost of maintaining a code repository goes toward maintaining the build.
• Multiple builds per repo create significant costs.
• Any web application with a UI _requires_ a frontend build for CSS/JS. Anyone around from the JQuery/pre-SASS days will recall the mess that lack of things like dependency management and ability to control import order caused.
• If the frontend build is already baked into the process, you can save costs by _only_ using a frontend build.
• SPA patterns are the easiest to use with a frontend build, have the most examples/comprehensive documentation.
The vast majority of sites out there would be just fine, and in many cases much better, as traditional server-rendered pages with a thin layer of JS on top for enhancements and for islands of interactivity. That massively reduces the complexity and cost of creating and maintaining a build.
Most of us aren't working on anything that requires the entirety of every page and the entire navigation model to be implemented on the client.
What I fail to see is how React is responsible for any of this because this sort of reads like his wife left him for one of the React engineer or some shit.
If your use case is a simple website, React is just a nice templating lib and you won't need to use any of the things people generally dislike about it. That AND your experience when you inevitably have to add some interactivity is going to be 100x better than vanilla JS.
As for the build step, there are many turn key solutions nowadays that "just work". And isn't a small build step a plus, compared to being at the mercy of a typo breaking everything? To me that piece of mind if worth a lot, compared to whatever manual testing you'd have to do if you work with "text" files.
Are these templates only used on the server-side to generate the HTML upfront? Or is it being generated on the client?
> experience when you inevitably have to add some interactivity is going to be 100x better than vanilla JS
I don't believe this can quantified. How are you measuring DX improvements? Are you also able to continue to measure these improvements as your application/codebase scales?
I have a website. It's not great, it doesn't get much traffic, but it's mine :). If you disable JS, it works: links are links, HTML is loaded for each page view. If you enable JS, it still works: links will trigger a re-render, the address bar updates, all the nice "website" stuff.
If I write enough (and people read enough) then enabling JS also brings performance benefits: yes, you have to load ~100kB of JS. But each page load is 4kB smaller because it doesn't contain any boilerplate.
Obviously I could generate the HTML any way I choose, but doing it in React is nice and composable.
Why do you think that? What problem is a build tool solving for you that without it you think you're being irresponsible for not doing it by hand?
I’m saying—if you do not have high interactivity requirements, which I would claim is most things on the web—you will encounter a lot less overall complexity shipping mostly server-rendered pages with isolated, self contained JS bundles where you need them.
I was using multi-entrypoint build steps outputting separate per-page or per-feature CSS and JS bundles long before I ever worked on an SPA, it’s hardly a good reason to move your entire UI and routing to the client-side.
There are many ways to render pages on the server using a single JS builds, most template rendering engines have a node implementation, and most javascript frontend frameworks have a mechanism to render components statically to a string. If we're talking about a simple, mostly-static website, the content is going to be cached so the performance of the backend isn't a huge factor. So just use JS for the whole thing, and save yourself a build.
This is outdated nonsense for most sites.
I sincerely disagree. I am not about to add node to a project that gets by fine with Django + HTMX.
I'm tempted to say that adding hundreds of perishable npm packages to a project is a better heuristic for 'malpractice'.
Modern CSS is amazing. Why on earth would anyone use SCSS? It pays to look at what Vanilla can do these days.
> Even a "thin" layer of JS on top requires some degree of dependency management
Use modules and import away. If it is truly a thing layer, there's no need for further optimisation until far along in the product.
You say it like more those features are desirable.
> then have fun explaining to your product person why it took so much time to build a thing that they know very well is a pre-built component
Sure. I wasted more time getting an assortment of pre-built components to behave than I did building the basics from scratch. And then comes a breaking change. And then that component library uses styled components and doesn't run properly on the server. Why do people do this to themselves?
Except it really doesn't. Core web technologies have gotten so much better since the jQuery/pre-SASS days that you can absolutely get by without a build step.
- http/2 makes bundling a questionable choice
- polyfills are pretty much no longer a thing
- CSS now has most (all?) of the features that people used SASS for (variables, nesting, etc.)
- es6 modules work
This has been a big talking point in the Rails community lately — one of the big selling points of Rails 8 was the fact that you can, by default, ship a whole webapp without a build step, and that this is considered the "happy path".
Maybe in 5 years this will be a practical approach, but there's a reason that old ways of doing thing hang around: they're well-documented and reliable.
And perhaps most important of all: it's the tool we know.
>But why would OP or I switch away from React when we believe it's mature, stable, fast enough, and has a huge community, resources, and ecosystem?
Yeah fair enough.
Lots of massive paradigm shifts with little backwards compatibility.
I’ve gone through like 3-5 times where there is some massive changes between versions.
Right now they are pushing some new routing mechanisms…
I'm suspecting they are going to drop backwards compatibility again in the near future by deprecating support for the options API - leaving me with another headache.
Has gitlab finished upgrading yet? Last time I checked they spent 2+ years and that’s with codemod tools and super smart engineers.
At work, I spent a month upgrading one project to work with the compatibility build and we’ve been slowly migrating for the past 18 months. After the end of this year, we should be out of the woods for that project but then we have 3 more so…
Luckily, Evan has said that he has zero interest in fracturing the community again and I believe him. The new architecture of Vue 3 also makes it very easy to adopt almost any new paradigm into Vue as evidenced by the numerous demos Evan has made to compare Vue to other JS frameworks like Svelte and Solid.
Vue templates are, well, yet another funny little template language. The hello world example already seems way too magical. Just let me use the language I already know.
I will say though that solidjs seems like an improvement on react though.
Long may the reign of typescript, nodejs and react continue.
Last time I looked at react was 2016 or so and every tutorial was referencing some different mutually incompatible version of some component (router, redux, flux, some other alphabet soup) and everyone had their own list of essential ingredients in a basic hello world app. I came away from the whole experience thinking here’s an ecosystem that needs to mature another 10 years or so before I want to even look at it (I’m not a frontend person, it’s all academic to me.)
Is there a consensus on any of it yet? How to do routing, state, builds, etc? Or is there still as many combinations of components as there are tutorials?
Routing: react router (not very good imo but widely accepted and good enough)
state: No libraries. Just use “useState” and if necessary “useReducer”
Builds: vite
Then pick a query caching library so you don’t need to treat fetched data like its application state… ReactQuery is widely accepted and very good. Apollo if you’re using graphql
Unnecessarily complicated and confusing, with odd choices in the most recent version (that IIRC are not backwards compatible). I went with wouter after searching around.
> state: No libraries. Just use “useState” and if necessary “useReducer”
useState is the same thing as the old setState, and useReducer not much different - they're not sufficient for building an app because you just revert back to the original state antipattern, prop drilling.
If you really have too many props or need to widely disperse the same prop you can refactor using higher order components or use a context. A separate state management library isn’t necessary unless you are building something with a ton of complex UI state like a photo editor or a music production workbench.
I'm also glad that the local-first movement got some traction.
- a web site -- which has low interactivity requirements. Blogs, documentation sites, etc, go here. A vast majority of websites are in this bucket
- a web application -- which has high interactivity requirements. Things like Gmail, Linear, Google Calendar, and an enormous amount of SaaS apps fit in this bucket of things.
React is better at anything else at making the second. React developers happily pay the weird tradeoffs that come with it in order to efficiently develop the second.
React is pretty reasonably good at making the first, but the negative costs are more obvious.
As someone who has worked on one of the most consumed React apps in the world (Discord), I think the concerns with React are overstated. People want a good product, they don't care about the framework and it's costs. React is one of the most efficient (in terms of developer productivity) ways to get there.
I'm not a React loyalist; I would love to see someone dethrone React. My ears are always to the ground for new developments in technology. In my opinion it hasn't happened yet, but I would be surprised if it never happens.
Mithril.js beats it in my opinion.
I’m sure many developers would argue in favor of other libraries over React.
React is simply the most popular.
I tried to be neutral in my reply, so if you like it then I'm glad for you, and I hope your colleagues find gainful employment when they have to go to their next job that also uses Mithril. But I hope I never ever have to work in an organization which thinks a shitload of m() functions is easier to read than JSX
And Mithril supports jsx. (Not to mention the advantages gained by avoiding JSX in favor of hyperscript)
Might be best to actually use it in a small (or large) application of your own design rather than judging prematurely.
(I’m not suggesting large orgs use Mithril, as other commenter mentioned, community in some situations is more important than the tooling. But “building a web app” does not necessarily imply “employing a team of local developers to build a web app asap for less than x usd”.)
But is that not the crux of the article? So much of the web is the former but is built and distributed as if it's the latter, with all the end-user downsides that entails.
I know we're not supposed to accuse people of not rtfa but sometimes it's a struggle.
I don't appreciate the rudeness. I wasn't rude to you or the author, don't see any reason for you to be rude to me.
Let’s not get ahead of ourselves. An enormous amount of SaaS’s _wish_ they were a web app. A good chunk of them would probably have a net-better UX by dispensing of this delusion.
Yes it’s hard to learn the mental model but worth the effort.
My one tip to make your life with react easier …. don’t use state except within a component, instead send document events …… makes react 10X easier.
Having said the above I don’t do any SSR and not a fan of it.
One reason it says that React is a poor choice is performance issues. But front end performance issues are almost never the most pressing issue to deal with. React performance concerns in the real world are typically measured in, at worst, hundreds of milliseconds. Yes, there are a few specialized domains where this will matter. No, you probably don’t work in one. Greater leverage can almost always be derived from improving the backend.
The second reason the author says is that it’s based on a legacy eventing system which supports IE. The author goes on for quite a while to say how bad this is, but I question the assumption it’s predicated on: the legacy eventing system never bothers me, and it doesn’t create issues visible to my users. As far as it seems to me, this argument is akin to saying that React hasn’t bothered refactoring an old part of the code base. Yes, that’s not great, but it hardly strikes me as a reason to drop a framework entirely.
Finally, the author doesn’t actually give a prescription as to what to use instead of React. This is, personally, where the argument really falls apart. React does make a set of tradeoffs, I don’t deny that, but most alternatives I’ve seen make a worse set of tradeoffs that shift more work onto the engineer. Of course, since the author doesn’t actually highlight any alternative, we can’t have a discussion about what you’re trading away, but I suspect that the author makes no proposal because he knows that any alternative would immediately be shot down as obviously worse than React.
Respectfully, I disagree on all of these points.
This is fine for solving random business integration concerns, but for application software we have to use on a daily basis, it really sucks.
Modern web applications sometimes feel incredibly shitty to use. Gmail, YouTube, YouTube Music, Reddit, Twitter -- these are all bloated, hulking, beastly things.
I'm really hoping Rust becomes popular for specifically web application development. It'll need to overcome the awkward WASM/DOM bridge, but then it'll sing.
Heavy software that users spend hours within are where those hundreds of milliseconds per action really add up. We should be angry about anything worse than single digit milliseconds with these tools.
We need an engineering culture of excellence in these domains. Channel the Steve Jobs energy to say this isn't good enough.
And more than it just sucking, it is unnecessary. We have mature, well documented, cost effective solutions for developing software that have been around from years to decades. We know how to develop software. The problem is people trying to develop software with web tools.
I think in the article writers mind here we are talking hundreds of milliseconds on first load and the majority of actions are instantaneous after that.
This can be achieved, but it takes some diligence and product mind focus to optimize what you can how you can and even big companies like Google don’t always prioritize this the way they should
Colour me doubtful. As long as the DOM is accessible in JavaScript, it can't be a first-class object in WASM. And no one is going to transfer the DOM into WASM and break every JavaScript app out there.
I'm curious, why?
This is a bad argument against Rust in the frontend.
Web frontend development is very nascent in Rust, but there's already cool stuff taking shape:
Maybe not to you, but it's by far and away the biggest complaint with any website or app that uses React/Angular under the hood in my experience. On any computer older than a few years, the sheer amount of JavaScript being demanded to be run creates serious system bottlenecks.
This is literally why I cancelled Spotify, because it's fucking absurd to me that I need a (then anyway) 700 MB app to stream music.
There are very few instances I can think of for the last 4 years where I heard anyone complaining like this about the general state of these things. There’s a few offenders I can think of, like Salesforce, but I haven’t heard from any non technical users especially about things like Gmail being slow or their browsers being too slow.
Whet I often hear instead to be honest is people widely seem surprised when they have 200 tabs open in Chrome and everything still feels fast to them
That’s not to say performance isn’t important, it really is, in fact I’m the performance czar where I work, I spend along time on optimizations and performance.
However the acceptable performance threshold is dependent on the activity more than anything I’ve found. That’s why it’s such a big deal in e-commerce but people don’t seem to care as much for longer lived apps, otherwise Jira might actually be snappy
Now of course there is a threshold regardless of app where it will things negatively, losing customers etc. and thus it shouldn’t be ignore either
They ask me to call our ISP because it makes no sense that the sites they have used for decades feel so slow
All I could say was that there was nothing I could do.
YouTube is also great for this, like, 1/50 navigation clicks just results in a blank page with no error message. Ctrl-R to the rescue.
Or the number of times Reddit's infinite scroll just... dies. Somewhere in the background, I don't know where.
Like I can't think of any of these major platform websites where shit isn't just constantly tripping over it's own dick and breaking in often humorous but also just ridiculous ways.
They also don’t represent the overall web. I think it would be more far to take a sum of websites used, as opposed to number of users.
It’s a valid concern (as I think performance always is to be clear) but the majority are not on higher latency / limited bandwidth connections like 5G internet service as their primary ISP delivery tech.
Vast majority are in cable or fiber at this point, given urban saturation
They don't say "modern software is slow", they say "my computer is slow, I need to buy a new one" and they do.
Let's be honest: for what the vast majority of people do on their computer, there is absolutely no need for a Macbook M3. The only reason is that the websites are developed by people who buy (or get from their company) a Macbook M3 and therefore don't see how much their website sucks on a reasonable machine.
I can track it very well on my father's homepage which has been the same for 25 years. He has a 4 years old desktop mac and the webpage takes more than 20s to load. On an M3 it takes 2s. This homepage is still loading exactly the same kind of information than 25 years ago, yet it is almost unbearable on a 4 years old desktop computer. Does my father say that this webpage is slow? No, because all software goes like this. My father says that his computer is now old and considers buying a new one.
How long did it take to load 20 years ago, on a 20 year old PC/Mac ? - seems like a very big page?
And of course now it loads a ton of useless widgets, probably much bigger images (sometimes they load a video to serve the same purpose, just because they can), and a whole lot more code. And that's with uBlock origins; if I disable it it's a lot worse.
Objectively, in 25 years they have been paying people to make it an order of magnitude worse. And it's not only them: the vast majority of websites have followed that trend.
You only know that factoid because you're an engineer and you looked it up. Users have absolutely no clue, and literally do not care.
When their smartphone is 3 years old and has no more storage space, they say "the smartphone is old, I need a new one".
Because they don't know that this is a problem of the software industry being extremely bad doesn't mean that it has no impact on them.
Get out of your bubble.
I've never encountered anyone at all doing that though.
I disagree. Try loading up a library heavy site (i.e. React plus a half dozen associated helpers for state, UI and whatever, which is pretty common) on an old or cheap Android device. It can take multiple seconds before the page is fully loaded. Even once the libraries are loaded, React sites often involve parsing a giant lump of JSON before you can do anything, that’s particularly CPU intensive and takes time on low end devices.
> Yes, there are a few specialized domains where this will matter. No, you probably don’t work in one.
Again: I beg to differ. Anyone hoping that their site will rank well on Google needs to factor in site performance via core web vitals. Time and time again I’ve seen React-based sites perform horribly and it’s very difficult to dig your way out of the hole after the fact.
I actually think most of the problem isn’t React itself, it’s the ecosystem and the philosophy that surrounds it so often. You’ll have React, you’ll have some extra state management library on top, you’ll have some hideous CSS in JS bulk on top because no one wants to actually learn CSS… it’s all prioritisation of developer experience over user experience. And it’s industry standard these days.
My main contention with the OP’s point was the assertion that React is almost always the right answer. One of my biggest bugbears about any web dev discussion (particularly on HN) is that everyone treats it as a one size fits all argument and it isn’t.
If you’re making a webapp with interactivity levels like Gmail has then React is a sensible choice. The page reloads very irregularly. But if you’re making something like a blog with lots of drive by visits and only small islands of reactive content IMO it’s the wrong choice.
This is not the case. RSC solves the hydration problem, in which hydration is profoundly expensive (larger bundle sizes, more client JS to parse and execute, and slower time to interactive), when most of the UI on any website can be non-hydrated. This also gives you the ability to write server only code (which as it would turn out, reduces sending third party deps to the client even more) for free with beautiful composability to client side hydration when you need it.
Everyone hydrates at some point. Maybe you write isomorphic javascript or maybe you render a rails or python app and sprinkle in some JS. RSC enables you to do this with complete composition and re-usability.
I'll put my money where my mouth is: RSC will continue to grow in adoption and its patterns will be adopted across many UI frameworks and libraries. This wasn't a solution in search of a problem, this was a large step forward in giving us more optionality as to how we architect websites.
> There are too many devs out there only expert in the way React does things and can’t step outside of it.
This is a weird ad hominem, attacking developers' skill instead of the actual technology. There are millions upon millions of React developers, and many of us have been building successful software for a long time and step outside of React every day.
> But if you’re making something like a blog with lots of drive by visits and only small islands of reactive content IMO it’s the wrong choice.
For some use-cases it is not the best choice, and for others it's the correct one. No one is hailing React as a one-size-fits-all solution, rather it remains a great balance that scales remarkably well to many needs.
I’m surprised to see people still misusing the word isomorphic.
More recently though — over the past decade or so — JavaScript enthusiasts have been using this word to describe code sharing, which isn't quite right.
I'm struggling to understand also how it came to be [ab]used in this context. To take an old Greek mathematics word and use it to mean something that it doesn't really mean? Why? Isn't that silly? Isn't it pretentious?
Server and client rendering? You must concern yourself with both. The best frameworks will not perfect abstract this for you. They can’t, it’s leaky. When the cracks show, it will be painful.
CSS-in-JS? I’ve used it and fought for it. Have you ever looked at the css output? That’s not a cake I’d want to eat. Compare it to a codebase with a well architected set of css and the markup and css actually do work for you. They are clarifying and reinforce structure. There are levels of productivity you gain based solely on things being clear and not convoluted that many people in our industry cannot recognize because they are fixated on the wrong thing. Whether that be what other people are using, or what gives dopamine hits (hot reloading, cool tech, etc)
It is a common saying, not to be taken "literally."
> The best frameworks will not perfect abstract this for you. They can’t, it’s leaky. When the cracks show, it will be painful.
Better than before with pure server side solutions like Rails or Django, however. I use RSCs and they work just fine, because you are using TypeScript on both the client and the server, meaning there are greater abstractions that can be leveraged.
> Have you ever looked at the css output?
Not sure what CSS in JS library you used but with something like Typestyle or PandaCSS, you write CSS but in JS objects, so the generated CSS is simply turning those objects into the CSS you already wrote, not sure why it would be any different.
They're quite different and it's a shame they're usually mixed up in these discussions.
So… a site that doesnt care about SEO and is not indexed and is purely for logged in users is also very common.
that was the case in 2015 when entry level android devices were quite slow, nowdays a cheap $200 android phone has at least 4-6GB of RAM and an eight core processor.
if that isn't enough for your react powered site, you are doing something very wrong.
And I don't buy that most websites would have react as the bottleneck, over the million other js libs, ads and tracking.
You need to take performance seriously or it will just be bad. Most of the industry has chosen to be bad.
Because demo sites are snappy on even low-end devices. It's not react itself that causes slowness, but all the other libraries/tracking/ads.
So at least be specific what is problematic, is it a particular framework, a particular library, the whole idea behind react (v=f(s)) or what? Anything can be proven against something non-concrete.
The entire site may take multiple seconds to load, sure, but it's quite rare that this is a React issue. Typically, the real issue is something like the website making a bunch of API requests in serial rather than parallel. For instance, the issue of JSON parsing that you cited is actually an SSR issue; that's entirely orthogonal to React, and you can make the same error in any other popular web framework.
> I actually think most of the problem isn’t React itself, it’s the ecosystem and the philosophy that surrounds it so often. You’ll have React, you’ll have some extra state management library on top, you’ll have some hideous CSS in JS bulk on top because no one wants to actually learn CSS… it’s all prioritisation of developer experience over user experience. And it’s industry standard these days.
I think you're saying "React is slow" when you mean to say "the entire frontend ecosystem is slow". To which I respond... sure? None of this is React-specific. If you don't use React, you'll still have to use state management (or manage it yourself; have fun!), figure out something to do with CSS, etc, etc.
It doesn't matter what library or framework is used - even jQuery can score 100% page speeds on Google Lighthouse. It really only depends on following every single nitpicky thing that Google Lighthouse recommends, and finding a solution for it. I took a site (actually a few thousand sites) that was scoring about 5 to 35 out of 100 on Google Lighthouse (depending on the customiztions), up to 100/100 on Google Lighthouse. It took a lot of work, but the clients are happy now.
Where React doesn't do well is with lots of DOM elements. In another project I created a complex web application that had about 3000 div elements with drag-and-drop interface and all kinds of stuff going on. Well React couldn't handle it. The browser started crashing due to memory issues if the page was open longer than 20 minutes or so, it slowed to a crawl and eventually froze. I ended up switching that one component to a canvas based solution (Konva) and it solved the problem completely. I still use React for all the other simple UI stuff, but I learned my lesson about what React is really good at and what it's not.
On the other extreme, completely deferring any loading of 'below-the-fold' content until it's visible can also have horrendous consequences, if that loading involves downloading any external resources. Not every visitor can just make further requests near-instantly, and it's those RTTs that really slow pages down, in my experience. Excess API calls are just one (very common) source of excess RTTs.
The obvious compromise would be to load 'below-the-fold' content ASAP once all 'above-the-fold' content is finished, unless it's unacceptably heavy for the target device. (Then again, some people still won't be happy: I recently talked to one person who derided the load times of a certain blog, but I found that all of its meaningful content was loaded and visible very quickly: they were only taking issue with the Disqus comment widget at the bottom at the page.)
It’s unacceptable. React touts its shadow-dom “because it’s much more efficient than updating the DOM directly”, well, that’s a big lie.
React is better than all predecessors, but it’s still the wrong abstraction.
We use a "loading" spinner. People know they have a shitty computer, and they'll wait an extra second instead of spending $1000 on a new computer. That kind of page speed problem isn't one we could ever fix, and it's something the user is typically well aware of being on their end, because every site is slow, not just ours.
> completely deferring any loading of 'below-the-fold' content until it's visible can also have horrendous consequences
We use a combination of lazy loading and SSR (not React SSR, it's hosted on a custom CMS). Content is SSR to maximize SEO. In some places we'll only render the first 3 or 4 items and then lazy-load the rest if it's a lot of data. Too many DOM elements at page load is also bad for the page speed score. Javascript is lazy-parsed, meaning the text of the script can be loaded in-line, but not parsed until the page is scrolled and the content is in view. Loading the text of a script isn't what slows the page down, it's the parsing of larger scripts that causes page speed issues. When the page scripts can be parsed in smaller chunks, the scrolling experience can be more fluid and the page speed test is satisfied. All images below the fold are lazy loaded. All 3rd party widgets are lazy loaded where possible, because they all suck and they mess with page speed pretty badly. There are lots of other tricks to get to a perfect 100 score on Google Lighthouse. Fortunately for us, "below the fold" is generally easy to accomplish across all of our sites, by the nature of the type of sites we are building. It doesn't work for all kinds of sites, but for ours it works very well.
I really hope nobody takes this "advice". What are you trying to save me from?
>Sure you can load scripts in-line for stuff below the fold, but make sure it doesn't actually get parsed by the browser until that feature is likely to be visible on the screen."
I specifically said you could load a script in-line for stuff "below the fold" as long as the browser doesn't parse it until it's used. That's very different than doing an HTTP request for a script file while scrolling.
But you know what? Forget it. I'm done trying to explain things to people who think they already know it all and didn't even understand my original comment.
> We use a "loading" spinner
> users can wait an extra second [every time they scroll to load new content]
which is exactly the bad experience the commenters above are talking about.
They understood your comment, and they disagree. This is not the good advice you think it is, unless your main goal is to score 100 on lighthouse for SEO purposes, not UX.
If I can't skim your page instantly I will more than likely churn my visit.
Doesn't matter that I have a good computer on a 1Gbps connection, you ruined my experience. I'd rather wait 1 sec for the full page to load, than wait a series of 100msecs on what should've been a fully loaded page to actually load at an arbitrary point in time.
You (and a lot of others here) are making a ton of wrong assumptions, imagining things I never said, and making up your own problems that don't exist in my code just to try to bash me, without even really understanding anything that I wrote in my comment. This entire thread sucks and is full of low-quality trolls. I've been doing front-end for ~30 years, I know what I'm doing. Don't bother replying, I won't be responding to further wrong assumptions and bashing.
This smells of a memory leak, particularly if you forgot to add a dependency to a hook for example, but there is plenty of non react related code that could go wrong with drag and drop interfaces too
I would think that using React as an SPA application makes sense, but not if you want to sprinkle some interactivity inside some html pages.
My React app is statically exported and cached by the browser. There is only a single graphql call that fetches all necessary data. Backend is my only bottleneck. Everything else happens in less than 10ms.
And yes it is entirely possible to shoot yourself in the foot with any language and any framework. Including React.
That isn't necessarily specific to react, any client-side rendered framework will have issues. React tends to be noticeably worse in my comparisons though, and any client rendering is going to be worse than server rendering your HTML.
In a typical web application use case (yes, there are exceptions) you're only rarely looking at usage from old or cheap Android devices. Occasionally you'll see a tablet, but even that's rare. The vast majority of the time your users are on either Chrome or Safari on a relatively modern Mac or Windows machine. In many cases the application loads once at the start of at least 10+ minutes of work, so initial load times rarely matter much.
If you're building a website that needs SEO, then yeah, React is completely the wrong tool, and you should just make a proper static site or hook your marketing team up with WordPress (or whatever takes its place once Matt is finished blowing it up). But those use cases, while common, represent a tiny fraction of total engineering effort across the industry, so most web developers here don't have the design constraints that make React a bad choice.
On what basis do you bet this, though?
Sure, you see sites that bug you by being slow in contexts where you'd choose something else, but most devs are working on sites and apps that you will never see, because you're not the target demographic.
I don't have survey data one way or the other, but anecdotally everywhere I've worked on an SPA has been a clear case where trying to do it in backend+JQuery would have been a huge failure.
There are a bunch of stacks that I prefer to work in for my own projects, but what I need at work is almost always the standard option that everyone is already used to.
Pre-rendering everything has downsides of course, but it doesn't get much faster than that.
I think it's also a misconception that there is such a clear divide between app and content-oriented websites. Even the most content heavy websites, news sites for example, are highly interactive these days. Show me a popular content heavy site that doesn't have some sort of log in, interactive content, comment section, filtering, live blogs, alerts, notifications, search, and similar.
You also have to take into account the advantages of pre-fetching links, and only fetching and replacing the content instead of doing full page re-renders. All of these great things you can do easily with React and a React framework of your choice. You can even go further and have a hybrid of statically exported pages, SSR, and some SPA like highly interactive parts, reusing the same exact components in all these strategies.
All to say: React can be a great choice for a lot of use cases, also for content heavy websites.
There are plenty of easy to use virtual scrolling libraries for React and vanilla JS. There is also `content-visibility` with CSS Containment now.
And I have been saying this for well over a decade. Hopefully it catches on.
I have always asked for example of sites done in React where I couldn't tell it is done in React or other JS Front End. The "at worst, hundreds of milliseconds" is precisely why Web Apps never felt as good as native apps. And if we collectively cant make web apps good, why not go back to Interactive Web Pages that is mostly Jank Free. I say mostly because it is still not Native Apps level.
Recently submitted, [1] why does liking a tweet re-render the entire screen? done using [2] React-scan.
They're probably using Redux, which has been the go-to for state management in React for nearly a decade. I've always been averse to it because it's implemented using contexts and triggers those full re-renders - it was designed during the class-based components era and relied on people actually implementing shouldComponentUpdate(), which isn't really a thing with modern function-based components.
If they were using modern hook-based state management like Zustand or Valtio, full rerenders wouldn't happen.
That being said, none of the React projects I've had the chance of working on in the last 5 or 6 years has used Redux, so stating that it's been the go-to state management library for nearly a decade kind of sounds weird to me.
My Core-i5 24GB of RAM desktop PC that's 8 years old can pretty much do anything I used to do in 2016, except smoothly run React websites, some of which are verging on becoming unusable.
This is nuts. People should stop using their M3 Pro Macbook as a benchmark for what's 'fast enough.'
I understand the desire to work on machines with lots of power and memory with a nice high res display and fiber connection. It makes the experience a great deal nicer. Even so, we should be keeping old and/or thoroughly mediocre devices around and testing on them periodically so we don’t succumb to illusions of good performance.
What almost always happens is that with a SPA the core business logic is more or less separate from the bits that are shown in the browser, so that if AngularJS gets deprecated you still have an API that you can use for your Vue/React/Angular rewrite.
However, if JSF becomes too much of a maintenance burden, the chances of me migrating to HTMX or a similar technology, even a full on SPA are pretty close to 0% when I have only a similar amount of time as in the case above.
Why? Because the previous implementation is going to be in the same codebase and like it or not, as more time passes and as more people work on the codebase, there will be coupling. Those technologies will intertwine to such a degree, that a clear cut replacement will be really difficult.
I guess what I’m pondering is why we don’t have an RPC/IPC component as a central part of Django, Rails, Laravel, JSF and all the others - so I could have server side rendering but separate repos (with separately managed dependencies) for the back end and the front end.
Maybe even deploy them as separate containers that talk to one another and have resources managed separately, so the old JSF permission check logic for rendering components in a deep tree cannot eat the CPU time that’s needed for some scheduled processes in the back end.
Try doing it on a flagship handset like a Pixel 8 Pro, and it's still a slow and miserable experience.
m.facebook.com, as an example.
Likely many developers don’t even know how to build something without React. They don’t know the first thing about html, server-side rendering, progressive enhancement or any of the things we used to use to build forms over data applications before React came along and its siren song drew away many developers, and, worse, created an entire generation that fits the criteria I’m describing.
The author doesn’t need to describe an alternative any more than he did, because the alternative is supposed to be self-evident. If it’s not, the person is supposed to take the plethora of breadcrumbs in the article and figure out how we used to do things before bloated, convoluted, and typically unnecessary frameworks.
When you look at something like Remix and Next you see people trying go back to the simple (forms, server rendering) by adding additional complexity. It’s doubling down on complexity, rather than finding simplicity.
I've made websites in so many stacks and varieties that it would be intensely boring to list or read them, and I have NO IDEA what he thinks is better, or even if he is able to disambiguate the React architecture from the React library/stack, or which one he is talking about.
It's a tome, a full tome, without a clear position.
Mine is this: a truly state based rendering and eventing engine for frontends is a dream, a beautiful dream, not unlike the beautiful dream of a purely functional language based on the lambda (or rho?) calculus. The dream giveth and it taketh away, and it is always a fundamentalist dream; where that fundamentalism hits the cracks of reality is where engineers have to make tradeoffs.
The React architecture stack (well, the stack without prop drilling) stays somewhat beautiful as a dream in my opinion, which is to say it provides guide- and guard-rails to stay relatively productive delivering mid size applications across millions of devices without a ton of moments where I'm like "what the fuck is the rule of hooks, and how did I break it here?"
The react library stack, and by extension the node stack: sucks balls, full stop. I'm happy to get some other framework which has write/compile-time type safety, modularity and an eventing/rendering system that abstracts away most of my concerns for delivering over the web and is lighter weight, has less dependencies, etc. However, if the author wants me to change my ill-begotten ways, it would probably be more effective to explain how it is that each of the items in his list: "Preact, Stencil, Svelte, Lit, FAST, Qwik, or any of a dozen faster, smaller, reactive client-side systems" provide a better world.
In this area, I believe I'm a journeyman, reading a senior / master engineer's writing -- fine. But he is not informing me at all. I don't want to go learn the recommended 18 (12 unnamed) smaller client-side systems that apparently require less mental bookkeeping of me. I'm not even sure what that means -- I code tsx in vim, and do not feel like I have to do a lot of bookkeeping.
So, back to you -- what's your recommendation? I'm genuinely curious what you think would be better. Or the author, if he wants to butt in here. I just don't understand what you (or the author) thinks should be done. The forms processing and server rendering (say with Perl 5 and tcl were two early langauges for me) were not that great.
It'd be rather challenging to write guidance on which technology to use to build an application. Thorough guidance would need to consider far too much. You wouldn't have a tome, you'd have an anthology. You'd have to consider what is being built and by whom at the very least.
It becomes "self-evident" when you have enough knowledge and experience to make the selection and you successfully de-bias yourself from the "shiny" or the "common" (Which React was and is now respectively).
So, what would I recommend? Aside from the pat, "it depends" answer, I would recommend starting with a server-rendering based framework. I prefer Rails, personally, because Ruby works well for me and my team, but many others would do just fine.
Then, fight all superfluous interactivity for interactivity's sake in your applications. Stick to server rendering and form submissions until you need something more elaborate. Then, look for something you can use to augment behavior. I use Turbo/Stimulus, with which we are able to do a lot with very little. Others like HTMX. If one really needed the interactivity and declarative nature of something like React, then the list that the author mentioned would be good to explore. Most folks don't, and I think that's the main point that's lost on many.
Oh, and if you're building Google Maps, Miro, Linear or the like then disregard the above suggestions, they don't apply. Etc. (again, it depends)
As an aside, I was historically a huge React fan. I used it for quite a while. I'm still a fan of the declarative nature and one-way data flow. It's super powerful stuff. We actually get something somewhat similar with Turbo and the much more sophisticated Phoenix LiveView (can't recommend this one personally, haven't used it in anger). Procedural-based UI code for complex, highly interactive applications is a fool's errand in my opinion. For the basics though? Totally fine.
Don't get me wrong, I would much prefer coding in a single language for both backend and frontend, and I would not choose JS/TS for that. But your choice is that, only a decent choice. Just like react is. There are so many ways to do web development, and neither of these are fundamentally bad.
Specific applications of these architecture/designs on the other hand can be catastrophic in both cases, and I'm sure most of us has been burnt by these (e.g. for SSR, I have seen code that sent back HTML segments that reused IDs. With dynamic JS it was a pain to hunt down these errors. But there is an entire field dedicated to all the vulnerabilities that have historically been opened up by careless backend devs).
"Now" being what specifically? The technologies I mentioned allow everything to happen on the server. We've got a relatively complex set of applications: 30 deployed apps, composition using SSI (server-side include), collaborative form entry for complex form including sections that appear/disappear, etc, near-real-time comments, etc. We have on the order of 100s of lines of JavaScript and I don't think there is a single JSON API (so no DTOs).
> But there is an entire field dedicated to all the vulnerabilities that have historically been opened up by careless backend devs
This may be part of your problem. The people returning the HTML are front end devs. Rails and the like are front end frameworks. The server is just the server of the front end. This notion that "front end" is just React/HMTL/CSS is a new thing that can be problematic as you describe. It's all front end stuff, always will be. You can tell because of what's happening with React with server-rendered components, NextJS trying to blur the line, etc.
I'm suggesting that if your perspective includes this kind of dichotomy and you see different teams of developers working on client-side than on server-side, you have to first address that as a problem.
As I said, this is definitely a viable approach, but so is react. Both would fit like 80% of all websites just fine, given that they are developed by decent developers.
A forms over data application can be built with React. That's "valid", but what is the cost? The latency in showing/hiding things can be seen with slower internet connections, but so what. What is the cost of that? Have you ever used an air travel booking site? Many of those interactions are painfully slow but you still booked your travel, right? Now take those slow interactions and make them so they are actually just on the edge of human perceptibility (which is easy with server rendering) and you've got a perfectly great experience for your users. If your users are captive (it's their work application, or they need to book travel, etc) then you have even more (but we wouldn't need it) leeway.
If you're a shopping site where revenue is tied latency, maybe it's necessary? But have you used Amazon? There's all sorts of server loading there and they do pretty well.
I'm not claiming that React is "slow". It's slowER on time-to-interactive on average. It can be slower to develop applications. It is certainly more costly from a maintenance perspective due to the unstable nature of JavaScript dependencies.
I'm not going to be able to convince you of any of this. I'm only here holding a sign saying that things aren't as straightforward as they seem. There are costs and costs and costs to this stuff that many see as a normal day in the office.
I'm just saying there's more productivity beyond the horizon, and you're not going to find it by embracing and extending complexity. React is complexity. All the things that come with it to compensate for its complexity are more complexity.
Teams go faster permanently by embracing simplicity. Using React for a forms over data application is the opposite of that. You can do it. You can get your first version out "quick" but over time, that complexity will rear its head and you will slow down.
Have you ever been on a team that wasn't as fast as it was on the first day of a project?
Basically, I know how to build a server side rendered application, I still reach for React, I know it sucks in so many ways, accessibility, performance, complexity, and so on. I just don’t know what to pick instead. It’s the first time a framework allows seamless refactoring into composable components. Powerful, terse and type safe templating language. Clear separation between state and presentation. The developer experience is just easier, even accounting for the additional rpc needed between client and server and the hook footguns.
Do I wish there was a better way to do server side rendering. Of course. For server side rendering to take off, the story for how to gradually add interaction need to be better. Not everything is static text. The moment you need something interactive, even the most fundamental thing: date picker, form validation, expand/collpase, selection, reordering, lazy loading... sprinkling in a bit of js in a server side language become an unmanageable mess. Trust me, I’ve done it with jquery, it can get the job done but it will be a compromise, nowhere near the ease and accuracy that react gives.
The JavaScript code that manages the collaborative form I mentioned is around 300 lines. Every new form we build is just Rails partials with helpers. No APIs, all server-rendered. It works very well. It loads faster than the React version and it has observably less maintenance cost.
> For server side rendering to take off...
> date picker
A reasonable one is built into most browsers now. You don't tend to anything more unless you need something specialized, and then there are libraries you can use (or you could reach for vue/preact/etc w/ the so called "islands" technique)
> form validation
On the server with Turbo/LiveWire/HTMX
> expand/collpase
This can be done with just CSS and a hidden checkmark. The JavaScript version is lines of code.
> selection
Not sure what this means
> reordering
There are libraries for this. By the way, I built a Trello plugin that effectively re-implements Trello within Trello including drag-and-drop reordering and I used Preact and one of the React DND style libraries (don't recall which now). There was nothing easy about it, but it was likely easier for my specific use case to use those technologies. That's one feature in most apps though (for us it was basically the whole thing), so if I needed it in this app, even if I reached for React/Preact, it would be isolated to that one feature. I'd try very hard to avoid it though.
> lazy loading
Turbo/HTMX make this trivial. Note that we use SSI (server-side-include) to compose web applications. This is all done on the server. Our apps are fast enough that we don't need lazy loading to maintain a very low response time even when hitting multiple servers in a request.
> Trust me, I’ve done it with jquery, it can get the job done but it will be a compromise, nowhere near the ease and accuracy that react gives.
So have I. Then I did it with React for over 6 years (including the transition to and from Redux and to hooks). I championed React and CSS-in-JS at my agency. Now I've done it with server-rendering again and different front end libraries (turbo/stimulus) for 3 years most recently. The difference is night and day. I have 15 other devs on my team that would tell you which stack they are observably more productive with. I'm just some guy on the internet, so take everything I say with a grain of salt, but I am uniquely positioned to be able to speak on this with practical experience on all 3 topics in this discussion (how server rendering was, how React is, and how server rendering is now).
Honestly, much of it comes down to what we let our "designers" force us into. If it's just the type of things that you described, it's server rendering all day. If it's random/unnecessary interaction/fluff/flare, the appropriate countermeasure is saying "no". Again, if it's Miro, Linear, Superhuman, etc, then sure -- reach for a full-fledged SPA framework/library.
And I think the crux of the problem is that there is no obvious alternative. That isn't to say it can't, or shouldn't exist. I'm not a React loyalist. I was a working frontend developer when React came out and I remember how it took the web community by storm, because it was an obvious step forward.
When the alternative exists, it will be as purely obvious.
I’m not sure I would rely on obviousness. Things are only obvious to the late majority after the innovators and early adopters have moved on. The thing to pay attention to is when people who have extensive experience doing the exact thing you are doing say there’s another way.
The really tricky part here is that that “other way” in this case looks similar to the “old way” and thus is easy to dismiss. It also doesn’t come with any of the dopamine inducing things like hot reloading and really cool tech like virtual dom diffing, etc. in other words, it doesn’t speak to the parts of us that are drawn to the “cool” factor. It’s simple, it’s basic, it’s sometimes tedious, but it’s productive — in the long run.
1. Component based architecture
2. The ability to express view as a pure function of state
3. The ability to express HTML and code together in a neat and ergonomic way
This is what I mean by obvious -- all experienced frontend engineers I knew at the time immediately got it, they got that React nailed these three things, and why they were important. Surprisingly, even new frameworks don't always lead with these three principles, which makes me less likely to believe that they resolve the particular concerns that I find of most importance.
And yes, I ended up falling for React for these reasons and more. When we moved to Rails server rendering, I even experimented with rendering React components from the Rails server. It worked, but the rube-goldberg contraption wasn't worth it.
Instead, we opted for helpers and view partials. The limited behavior we needed on the client would be in a separate Stimulus controller. The helper would typically reference it. Then, the declaration in the view would look more or less like a React component invocation, albeit with a totally different syntax.
There may very well be room for improvement here, but it certainly works "well enough". As I've mentioned, the main thing that is different now is that we can render updates to views on the server. This allows us to have "The ability to express view as a pure function of state" on the server and not have to be concerned about everything else that comes with owning and operating a React implementation.
I think React really helped move things forward and I don't regret my time using it. I may even use it again if I worked on an application where it was warranted.
I wish I could spend time with every commenter on here showing them our code, working with them on it, and helping them see the way that we do it so that my words don't just sound crazy or anathema. Unfortunately, that just doesn't work out in practice. I appreciate the discussion all the same.
This is actually something I think a lot about, because in my company I am the TL of all the setting pages. We don't have high interactivity requirements, and it's reasonable to explore a different path. But the core product is in React, and there's basically no justification to rebuild it in something else just to build out settings pages.
> I am the TL of all the setting pages
Ok, now I'm intrigued. If you're interested, I'd love to hear more about this. As someone who has (aside from a 2 year stint at Microsoft) only worked on relatively small teams (15 max) I'd love to hear more about what it's like to work on a team that's responsible for the settings pages. If you're interested, I'd be happy to connect for a chat. I just added my contact info to my profile here. If not, no worries! Cheers.
The problem is building a front-end UI with compositional components (essentially the only way to build anything substantial), with sane handling of state, and with acceptable performance for interactive use (which means not round-tripping to the server every time, sadly, otherwise I'd keep using Wicket). Almost everyone doing front-end work has that problem, which is why React is a good "best practice". It's rightly the orthodoxy.
> They don’t know the first thing about html, server-side rendering, progressive enhancement or any of the things we used to use to build forms over data applications before React came along
Which is smart of them. That stuff is an overcomplicated waste of time. I mean, occasionally you need to debug some HTML, just as occasionally you need to read the disassembly of a binary, but most of the time there are more valuable things to learn.
Server-rendered front end frameworks (like Rails) have units of composition as well (partials, helpers).
> with sane handling of state, and with acceptable performance for interactive use (which means not round-tripping to the server every time, sadly, otherwise I'd keep using Wicket)
What "state" one needs to handle is app dependent. Some do need client-side interactivity and some don't. Obviously, if you need it, you need it. Saying "almost everyone doing front-end work has that problem" is something you'd have a hard time proving. Historically, most things people have built on the web have had relatively low levels of interactivity. There are brochure sites (read-only) and there are forms-over-data (read, with data entry) that both lend themselves well to a server-rendered approach. There are even more interactive applications like hey.com (a full-on email client) that is server rendered.
My team maintains 30 or so Rails applications complete with collaborative two-way sync form entry and real-time (enough) commenting with server rendering and Rails. The first app we built used React. I can tell you with absolute certainty (because I've done it) that the React version is still more expensive to maintain, still the place that the devs prefer to work the least, still the most expensive to extend.
> Which is smart of them. That stuff is an overcomplicated waste of time. I mean, occasionally you need to debug some HTML, just as occasionally you need to read the disassembly of a binary, but most of the time there are more valuable things to learn.
Are you trolling? The things I listed are "over-complicated"? HTML is what React renders. You need to write something like it when you write your JSX. Sorry, you gotta know that. Server-side rendering is necessary if you want anything resembling reasonable time-to-interactive or SEO. Progressive enhancement is something every web developer has to at least be aware of when it comes to CSS.
And, "debug some HTML"?
As soon as you have any kind of interactive UI, either you do sever roundtrips for everything (which is usually unacceptably slow) or you have client-side state. Tabbed form section? State. Two-level dropdown? State. Radio button enabling different parts of your form? State.
Theoretically it's conceivable that someone might have a website that needed only flat forms with zero dynamism. But I've found that everyone thinks their website is like that, and they're always wrong. Every Rails/Django/Wicket/etc. site ends up needing one little piece of unmanaged JavaScript somewhere (unless you're lucky enough for a server roundtrip to be acceptable latency-wise). And then one more piece. And then you have a state management problem.
> My team maintains 30 or so Rails applications complete with collaborative two-way sync form entry and real-time (enough) commenting with server rendering and Rails. The first app we built used React. I can tell you with absolute certainty (because I've done it) that the React version is still more expensive to maintain, still the place that the devs prefer to work the least, still the most expensive to extend.
You must see that your experience is unusual - perhaps you're using React badly (understandable in a first app), or your team has spent more learning time on Rails. There are scenarios where Rails might beat React on a level playing field, but this shouldn't be one of them. Apart from anything else, how do you do handle the client-side state in the Rails case?
> HTML is what React renders. You need to write something like it when you write your JSX.
Right, just as your Ruby runs via a C interpreter that ultimately executes as machine code, is the analogy I was drawing. Having a bit of familiarity with C and your processor's assembly might be helpful for some kinds of debugging occasionally, but it probably shouldn't be a priority.
> Server-side rendering is necessary if you want anything resembling reasonable time-to-interactive
I assure you it isn't. In some use scenarios it might be, but I've worked on sites that were very fast without it.
> or SEO.
Perhaps - but not everyone needs SEO.
> Progressive enhancement is something every web developer has to at least be aware of when it comes to CSS.
It really isn't these days. Even a very inclusive baseline of browser support still gives you plenty to work with - e.g. flexbox is 12 years old at this point. It's entirely practical to set a reasonable baseline and just not do progressive enhancement (particularly since often the "worst" browser you're targeting - iOS Safari - is also the one that most of your customer base by value uses, so there's little to gain from progressive enhancement).
Yep, we have all this. Server round-trip is acceptably fast. Perhaps we are lucky because most users are in the US.
The interesting question here is, what is unacceptably slow? Why is it slow? If you really don't need any new data from the server, i.e., you are just hiding or showing something, you can use JavaScript. But I'm just here to say that it's more than possible to be "fast enough" for a forms-over-data application. Usually when developers tell me (and yes I'm a developer) that something is not fast enough it's because it's "human perceptible". That may be the measure for certain applications, but more often than not, it's a developer that's fixated on the wrong thing. They only see that, and they don't see the long-term productivity cost of using a SPA framework. You may tell me it's not there, but it is.
> You must see that your experience is unusual - perhaps you're using React badly (understandable in a first app), or your team has spent more learning time on Rails. There are scenarios where Rails might beat React on a level playing field, but this shouldn't be one of them.
It wasn't our first app. We're actually very well versed in it. I just looked it up and the first app I worked on w/ React was in 2014. I worked in it exclusively for 7 years or so before making what I thought at the time was a the very risky switch, mid-stream with my current client to server rendering. Almost the whole team knew React better. Using Rails wasn't just a little bit more productive, or a little better, it was night and day.
> Apart from anything else, how do you do handle the client-side state in the Rails case?
There's almost none. Some I can think of are persistent scroll (in a navigation panel or comments feed that persists through page navigation) and persistent comment drafts. Persistent scroll is about 100 line stimulus controller that stores the scroll position in session storage. Comment draft is also in about 100 line stimulus controller (only about 50 lines or so are concerned with it). It's all very simple. Event hook, write to session storage. On load, read from session storage.
For everything else, it's a server round trip.
Have you used hey.com? It's an email client built with server rendered rails. From what you describe, this should be impossible. Yet, it's not.
> Right, just as your Ruby runs via a C interpreter that ultimately executes as machine code, is the analogy I was drawing. Having a bit of familiarity with C and your processor's assembly might be helpful for some kinds of debugging occasionally, but it probably shouldn't be a priority.
It's a flippant analogy here because you can't get away from the HTML. Sure, if you never look at the dev tools, or you always use the React dev tools, you always see your HTML wrapped in React components, but uhm, it's HTML wrapped in React components. You don't write assembly and give it a C function header. Yes, I recognize JSX isn't HTML, className made very sure of that. But... it's practically HTML in terms of what you need to know to use it. Oh, just remember to layer on the additional cognitive load that some attributes are slightly different.
> I assure you it isn't. In some use scenarios it might be, but I've worked on sites that were very fast without it.
Anything is possible. We would have to define fast, however. I mentioned TTI. The article you are posting comments about has a whole table dedicated to how even with server rendering and React most apps fail to achieve good performance numbers. Furthermore, in order to get reasonable TTI, you either need a small app, or you need bundling, code splitting, tree shaking, all additional complexity. Look -- I rode the Babel (né 6to5), webpack, to esbuild, to vite, to whatever else wave. I was the guy that built the webpack configs for my teams and handled all the upgrades. I actually KNOW the cost.
> It really isn't these days.
Ok. Keep in mind it's always changing. Container queries? Clamp? Various things over the years have been useful to be able to use and worth doing progressively. I agree though that the gap is reducing. We hardly do any progressive enhancement. We are also not targeting markets that would benefit from it. We can luckily mandate an evergreen browser because of who our users are. Not everyone is in that situation.
If you're making something users don't have much choice about using - either an internal business app (the article has a box about those), or a professional tool that adds major capabilities - then you can get away with it, just as you can get away with quite bad UI in general. But if you're making something that has to appeal to users, perceptible and even imperceptible latency when they click drives them away. I'm not claiming it's rational, but developers "fixate" on it because it matters to users; I wish I could just keep writing Wicket, but I can't argue with the numbers or even just my own experience of what using these UIs feels like.
> they don't see the long-term productivity cost of using a SPA framework. You may tell me it's not there, but it is.
Why though? Like, there might be specific things React does wrong (and I know that Rails is very productive for some people, much as I hate it), but there's nothing fundamental about using an SPA framework rather than a server-side framework that should make it less productive. If I want a form with 2 dropdowns and 3 text fields, that's the same question in either context, and should take the same amount of code to answer.
> There's almost none. Some I can think of are persistent scroll (in a navigation panel or comments feed that persists through page navigation) and persistent comment drafts. Persistent scroll is about 100 line stimulus controller that stores the scroll position in session storage. Comment draft is also in about 100 line stimulus controller (only about 50 lines or so are concerned with it). It's all very simple.
Fair enough - you made it sound like there was a lot of client-server state that was relevant. If you haven't got state that affects the UI, maybe you're the unicorn. I've found that websites always need that kind of thing (tabs, radios, nested dropdowns) and once you have something like that you either have the state only on the server and the latency is high enough to bother users, you have state on the client in an unmanaged way and get horrible glitches when the server and client disagree (e.g. client is on one tab of the form but server thinks it's on another tab), or you have state on the client in a managed way and use an SPA framework (or something indistinguishable from one).
> Have you used hey.com? It's an email client built with server rendered rails. From what you describe, this should be impossible.
No, but I've used similar systems. Yes you can make them. Yes they feel fast enough, if you haven't used the alternative (especially if you happen to be located close to the server). But they're clunky enough that they can't succeed in the market.
> Yes, I recognize JSX isn't HTML, className made very sure of that. But... it's practically HTML in terms of what you need to know to use it. Oh, just remember to layer on the additional cognitive load that some attributes are slightly different.
The edge cases are what take the time when learning though. Like, yes, you probably do need to be able to read HTML-like syntax without getting confused. But you don't need to know the list of tags or attributes or the escaping rules or the rules about which tags are self-closing and which aren't or ... . You just use React components and follow their documentation.
> The article you are posting comments about has a whole table dedicated to how even with server rendering and React most apps fail to achieve good performance numbers.
Most apps full stop fail to achieve good performance numbers. It always takes effort. I suspect the average React app probably is slower, partly because React sites are generally newer and mostly because React lowers the bar for developer quality needed to get anything to work at all, but that doesn't mean there's a problem with the tool.
> you need bundling, code splitting, tree shaking, all additional complexity. Look -- I rode the Babel (né 6to5), webpack, to esbuild, to vite, to whatever else wave. I was the guy that built the webpack configs for my teams and handled all the upgrades. I actually KNOW the cost.
It's O(1) work though, or very close to it. I was the guy that used the existing build that someone else had come up with before I started working on that codebase. It continued to work, and be fast - I think maybe one time in a couple of years we got alerted that we'd done something that messed up the code splitting and we fixed it. Maybe it is complexity, but it's not complexity that imposes any real overhead in actual day-to-day development.
Then it's not a fixation. If, for your application, the difference between a 1-50ms interaction and a 150-400ms interaction matters, then you have reason to for that interaction optimize the performance. If your entire app is like that, then you're probably a particular type of app (superhuman, miro, linear, etc.). Don't get me wrong, I pay for superhuman because it feels like a native app and gets many things right. I would not pay for hey.com. But hey.com is actually relatively successful out there despite its sometimes-perceptible latency. Oh, and superhuman has perceptible latency too. Any time something needs to come from the server it takes that round trip time regardless whether or not that thing is JSON or HTML. The delta between those two is pretty small now-a-days, and typically not perceivable.
> If you haven't got state that affects the UI, maybe you're the unicorn. I've found that websites always need that kind of thing (tabs, radios, nested dropdowns) and once you have something like that you either have the state only on the server and the latency is high enough to bother users
I mean, we do. Our forms are pretty sophisticated. Things add/remove show/hide, and they update live as others make changes. The state just doesn't need to be on the client. You say maybe we're a unicorn, I say maybe people should consider whether or not they are a unicorn too, and maybe those unicorns are just horses developers think are unicorns. They may just be a lot more common than you (and others) think. We all like to think that latency matters to our app because we all read that article saying that Xms in latency cost $Y, but none of us stopped to ask if that article was about our app.
> But you don't need to know the list of tags or attributes or the escaping rules or the rules about which tags are self-closing and which aren't or ... . You just use React components and follow their documentation.
I'm not sure how to say this... but literally none of this is typically significant and certainly not any more significant than it is in React. In React you still need to know the tags and the attributes. Escaping rules? Yea, you need to know those too -- just the JavaScript ones. Self-closing tags? Just don't use them, or do if you know them, or use something like HAML/Slim/any other templating language to do away with those nuances. I'm not sure that arguing that HTML is hard to learn is a very effective platform. It's the thing that grade school kids learn to make web pages. Sure, there's edge cases, and understanding semantics is hard, but you don't need any of that.
> I suspect the average React app probably is slower, partly because React sites are generally newer...
This isn't why. It's because it requires a significant amount of JavaScript to load and evaluate before you see anything. That amount can get larger with time.
> It's O(1) work though, or very close to it. I was the guy that used the existing build that someone else had come up with before I started working on that codebase...
Right. That stuff is O(1)-ish, and maybe it's stabilized some, but having gone through the various transitions, I can say it's not free. Nothing is though, upgrading Rails took us a couple hours this time around because of a breaking change for our 30 apps. React comes with, as a baseline, significant complexity that is O(n): Client/server separation (APIs or phantom-APIs like Next.JS has), state entangled with presentation (See the whole smart vs dumb components for an attempt to address this), massive asynchronous concerns that cannot be fully abstracted away (suspense and the like), and probably more.
Folks can't see it until they step away from it and look back. I've done that for the last 3 years. Unless a person has done it, I wouldn't expect my arguments to land. Folks see things or they don't. Again, I'm only here to say: there's something to see that you may not see yet. I'm sorry I don't have anything more convincing.
> We all like to think that latency matters to our app because we all read that article saying that Xms in latency cost $Y, but none of us stopped to ask if that article was about our app.
Disagree, I've found that even if the page is, like, tax forms, latency changes the feel of it and affects how the user feels about your site, even if they wouldn't consciously say anything about the speed. I used to be similarly sceptical about a lot of design work - I felt like designers were just messing with the visuals for no reason - but once I'd seen the before-and-after with a good designer I realised how much difference it makes.
> Any time something needs to come from the server it takes that round trip time regardless whether or not that thing is JSON or HTML.
Sure. So e.g. one thing that shocked me is how important it is to have a loading state for your form submit buttons, even though it only shows for a couple of hundred milliseconds and you'd think it wouldn't matter. But it does, and that's the sort of thing that React-based UIs tend to nudge you towards doing by default, whereas with server-side rendering often it's a bit more of an extra step.
(A server-side rendering framework will probably have a nice loading state for basic happy path form submit buttons where they've put time and effort into polishing. But it will be ad-hoc rather than idiomatic, because that kind of detailed client-side state is fundamentally cutting against the grain of a server-side framework. Once you go slightly off the beaten path, into image buttons or custom button components or what have you, it becomes harder and harder).
> Escaping rules? Yea, you need to know those too -- just the JavaScript ones.
You always need to know the JavaScript ones. So the choice is between learning the JavaScript ones or learning the JavaScript ones plus some other ones as well.
> Just don't use them, or do if you know them, or use something like HAML/Slim/any other templating language to do away with those nuances.
Then you've got another language with its own syntax that you're learning. Writing everything in the same language really does help (admittedly I don't know how many other people stay away from JSX and do everything programmatically, but doing React and never writing HTML is a genuine option, easier than doing e.g. Rails and never writing JavaScript IME).
> I'm not sure that arguing that HTML is hard to learn is a very effective platform. It's the thing that grade school kids learn to make web pages. Sure, there's edge cases, and understanding semantics is hard, but you don't need any of that.
Well, we started this conversation with you complaining about React devs who "don't know the first thing about html". I don't know how literally you meant that, but my position is that learning just enough to get by is just fine, and putting more time into studying the intricacies of HTML does not generally have a good return these days. To the extent that React (or Rails, or anything) allows you to dodge learning those details, I consider that a point in its favour rather than against.
> it requires a significant amount of JavaScript to load and evaluate before you see anything.
It doesn't though. Like, I don't know how much effort it took to get the right build config etc. to make it work in my case, but it absolutely can be very fast. I'm happy to believe it's easy to make a React site that's slow, but it certainly doesn't require any superhuman effort to make one that's fast. I genuinely don't know what you have to do differently, because it didn't feel like I was doing anything special.
(At a guess I'd say committing full-throatedly to React and doing everything their way, rather than trying to half-ass things with useEffect etc. - just because that's the main thing we possibly did differently from "usual", and because most of the people who have a bad time with React seem to be the people who don't want to dive all the way in - but that really is just a guess)
I agree with this, but probably wouldn't about specific numbers or use cases. By the way, one of the forms on our app round trips in 75ms when selecting a radio button that controls which set of fields is visible below it. On the "Slow 4G" throttling setting in Chrome, the time increases to 620ms or so, which is noticeable enough for the interaction to not feel good. Our particular forms-over-data application is not typically used on mobile (there's too much data to enter), so this isn't an issue for us. It's all contextual. If it were an issue, we'd either use an SPA-like library for our forms, or we would send all the HTML to the client and use JavaScript rules to control visibility. It's one part of our app. We wouldn't let that singular use-case dictate our entire stack.
> A server-side rendering framework will probably have a nice loading state... Once you go slightly off the beaten path... it becomes harder and harder
Indeed, this is effectively built in to Turbo. There's nothing special about it, you add CSS rules (turbo adds and removes classes). That'd apply to image buttons or anything else you want to throw at it. You're making assertions here about it getting more challenging, but I can't tell if that's from personal experience or if it's hypothesis.
If a person started their career doing React and is still doing React, that person would have certain beliefs about things that wouldn't be true. I get the impression that most people I'm engaging with here haven't actually done what we're doing but they are somehow convinced it cannot work or that our use case (line of business forms over data) is so special that it can't possibly apply to anyone else.
> Then you've got another language with its own syntax that you're learning
Yes, HAML is a new language. Our designers can work with it. It's not much more complicated than, say, markdown. Learning new things is what we do, every day. There are certain developers that prefer to hone their skills in the one thing they know how to do. They're the ones that put "React Developer" in their twitter or LinkedIn profile. That's fine. That's a career path. I don't work with those people by choice.
> Well, we started this conversation with you complaining about React devs who "don't know the first thing about html". I don't know how literally you meant that...
Got it. It was somewhat flippant, I admit that. They probably know the first thing, but the concerns you're raising about tags and escaping and that sort of thing honestly somewhat reinforce my flippant assertion. If those are the things we are concerned about our developers having to know then I wouldn't want them anywhere near anything our users would touch. I think we may be used to working with different calibers of developers. I get that they're all over the map now, so this is just a another contextual difference most likely.
> ...studying the intricacies of HTML...
It's not sanskrit. I'm rather confounded by the FUD around HTML here.
> It doesn't though.
Ok. I've done it, so I know exactly what it takes, at least in the 4 or 5 different apps I built with various versions of React and friends. I also know that aside from the fastest machines on the fastest networks, there's not much you can do aside from server rendering to address the first paint issue/LCP issue. But yes, once you have the initial JS bundle, the rest of the site is generally faster. By the way, one of our 30 or so web apps we have composed into a single application with nginx/SSI still uses React. LCP is 1.2s on my M4 Max and on a page with slightly more data that doesn't have React, the LCP is 0.7s. Yes, the bundle is optimized. These aren't awful numbers at all, but I'm on the fastest machine there is pretty much. There's no loading shimmer stuff like AirBNB does. Speaking of user experience, that stuff is absolute garbage and I can't wait until folks realize it. Of course, they'd have to embrace server-side rendering though... :)
Just to be reiterate: I think there are plenty of good use cases for React like libraries/frameworks. I just think there are fewer than people think.
Well sure, but in that case it's no longer "it's solving a problem we don't have". It's solving a problem that may be low on your priority list, that you maybe choose to tolerate, or solve in a more cumbersome way, but it's still an undeniable pain point.
And if you flip the question, I just haven't seen the compelling case for server side rendering. If you have a specific case where something else does something you can't do with React, or does something a lot better than React, then of course do that something else, and if that something else happens to use server-side rendering then maybe it will be a tolerable tradeoff. But I honestly think that if React or similar had come first, we'd never have invented server-side frameworks as we know them (which is not to say that we wouldn't have e.g. a Ruby based convention-over-configuration framework - but I think it would have a state model closer to React's).
> You're making assertions here about it getting more challenging, but I can't tell if that's from personal experience or if it's hypothesis.
It's personal experience, but perhaps outdated, and I never was hugely into Rails specifically. The last time I checked in was several years into wailing and gnashing teeth about people fleeing to React, but only really offering a smattering of ad-hoc fixes to specific pain points. Maybe they've found themselves a good unified state abstraction now, but I think it would be a real struggle especially for a framework that isn't really component-oriented in the way I see it (and indeed prides itself on embracing HTTP and having routes corresponding to pages).
> Yes, HAML is a new language. Our designers can work with it. It's not much more complicated than, say, markdown. Learning new things is what we do, every day. There are certain developers that prefer to hone their skills in the one thing they know how to do. They're the ones that put "React Developer" in their twitter or LinkedIn profile. That's fine. That's a career path. I don't work with those people by choice.
I used to pride myself on knowing dozens of languages, but I've come to see much of that as superficial and pointless. Learning new things that expand the way you think is worthwhile. Learning new tools that you can apply generally is too. Learning yet another slightly different templating syntax or curly brace programming language usually isn't. And some tools have enough depth to them that you can spend years and still learn new, useful things. I don't know that React is one of them - I don't know it as well as I'd like - but these days I generally find it more rewarding to learn a deeper corner of something that I can use a lot, than a new standalone thing that doesn't have any general lessons to impart.
Yes, in that case, i.e., if it were a problem we had. It's NOT a problem we have though. That's my point. Not currently. Not in our context.
> But I honestly think that if React or similar had come first, we'd never have invented server-side frameworks as we know them
Not exactly React, but there was ActiveX, Flash, and Java Applets. Thick clients came first. It wasn't until IE6 where there some AJAX was viable. React came later to address additional shortcomings: procedurally updating the state of the document via jquery got complicated, and large organizations with poor development practices (e.g., facebook) struggled to maintain control of their application. They came up with React to help with this, and it did, but it brought its own host of problems. Declarative UI was what we always had with server rendering. They just allowed it to update. Btw, this isn't a new idea. We had something like this with ASP.NET as well, but that included the server.
Meanwhile, people like Chris McCord had already built a syncing library for Rails to solve these problems and, being fed up with the performance at that point, went to Elixir where he eventually built Phoenix LiveView. By then, React already had significant market share. Turbo's previous incarnation came out before then and its current one came out around that time or slightly after. Combined with Ruby's performance improvements over time, it was quite viable for many apps.
Also, note what's happening in React -- it's moving towards more server rendering. People realized they lost something by doing client only and they're trying to get back to it. Remix is an ode to the simplicity of old (which is really the simplicity of now, but they don't want to give up their React Components). I can't blame them in a way, React is a lot of fun to write a lot of the times.
> Maybe they've found themselves a good unified state abstraction now...
We've always had the database. That's insufficient for highly interactive applications where you need client-side state, which is likely what you mean by "unified". So yes, if you need "unified" state, and specifically the ability to change your UI based on changes to that state, React is great, or any of the other libs. The author was specifically concerned about React's current state (e.g. legacy IE6 support) and I'm specifically concerned about people reaching for React when they don't need it. That's because I've done it, I've seen people do it, and I see people continuing to preach the React orthodoxy which will lead to more people doing it. This thread is full of it.
Whether or not a person recognizes it, HTMX, Turbo, LiveView and its kind have greatly narrowed that gap. They've made server rendering just as capable at highly-interactive UIs in many more cases than many people think.
> I used to pride myself on knowing dozens of languages, but I've come to see much of that as superficial and pointless.
Sure, I can relate to this. But this is different than spreading FUD about having to learn a new language. That's easy. That's the easiest thing we have to do. I'm not suggesting to do it flippantly. I'm suggesting that sometimes it's worth it. When it's worth it, you do it and it's not a big deal.
> performance concerns in the real world are typically measured in, at worst, hundreds of milliseconds.
I think outside of the privilege bubble where a significant percentage of the world is in, these concerns are measured in the tens of seconds.
> it doesn’t create issues visible to my users
What do your users look like? What kind of devices are they on? Is it mostly mobile or desktop? Are they mostly accessing your service on cellular networks or not? Based on that, what does your INP look like? IMO you'll see the impact of React's legacy synthetic event system by looking at your INP because it's reinventing in userland what the platform already does well. This impact on INP is amplified on mobile and moreso on low-end mobile. See CRUX data visualised by desktop or mobile below:
https://infrequently.org/2022/12/performance-baseline-2023/#...
> Finally, the author doesn’t actually give a prescription as to what to use instead of React.
I think he does and that's a big part of this article. It's almost literally everything from the "OK, But What, Then?" section. The TLDR is there isn't a one-size-fits-all.
I did read it. I didn't want to go into depth debunking every single sentence OP wrote because I thought it would be obnoxious, but I'll write a bit more.
> The TLDR is there isn't a one-size-fits-all.
That's what I mean - the author gives no prescription. Saying there is no one-size-fits-all is not a prescription. I'll respond to a specific quote the author said, which I believe to be the crux of his suggestion:
> Teams that have grounded their product decisions appropriately can productively work through the narrow form by running truly objective bakeoffs.
Most teams do not have the privilege of being able to "ground their product decisions appropriately". Most teams - at least those in small to mid-size startups - will start out building A, route through A' and A'' and end up building B once they land on PMF. If you ran a "bakeoff" on A, you're going to be a bit upset when you end up at A' and probably run horribly technically aground when you truly find the right thing to build.
Yes, if at the point when you discover B you have the latitude to rewrite your entire codebase to fit your new criteria, then by all means, go ahead. That will definitely outperform React. I think the teams with that kind of latitude is an exceptionally small fraction of all teams, and the number of teams with the technical chops to do it correctly will be an even smaller fraction of that. The rest of us will use React, which is roughly 80% as good as the optimal solution.
Oh and, yes, if you work at a huge company who has found PMF and has the latitude to rewrite your code into whatever the optimal solution is, don't let me stop you. That is what Google and Facebook did, after all. I just don't think many of us are Google or Facebook.
Are you expecting a prescription? If so, what could that look like? Specific technologies? When specific technologies are appropriate?
> Most teams do not have the privilege of being able to "ground their product decisions appropriately". Most teams - at least those in small to mid-size startups - will start out building A, route through A' and A'' and end up building B once they land on PMF.
I don't quite understand this. A bakeoff is meant to give you space to figure out what technologies are appropriate for the service you're building for your users and taking into consideration what your developers like. It's a collection of proof-of-concepts so it's a quick and lean way to get data on what's more likely to succeed for you. I can accept that the technology doesn't make a product, so focusing PMF is important, but you also don't want to pick something complex that you can't afford to manage as you scale.
The worst thing I see happening is you reach PMF and need to continuing scaling, but you hit a high complexity wall that you can't move past till you manage it. All that unnecessary complexity you took on and didn't invest your already limited resources is now tech debt that's oppressing your forward momentum. Bakeoffs can steer you towards the simplest tool you need to deliver your product so that it can stay out of your way so you can focus on iterating and developing your product.
> The rest of us will use React, which is roughly 80% as good as the optimal solution.
How are you measuring this? A lot of the evidence for using a technology and running with it without managing the complexity turns out badly (see The Reckoning series by Alex). And React is a high complexity tool that requires a lot of continued management investment.
The thing that appeals to me about doing bakeoffs to find the simplest thing for my product is not that it'll be the most optimal; it'll be the cheapest to maintain. The less complexity you have, the less you have to invest in managing it.
> I just don't think many of us are Google or Facebook.
I agree. That's why I think it's best to pick the simplest tools we can afford to manage so we can get on with building our products. Facebook or Bluesky or Airbnb can afford to build their products many times from scratch and they can pay to maintain whatever complexity they take on.
Tell me your websites are unbearably slow without telling me your websites are unbearably slow :D
Try opening facebook.com; click the messenger, (+1 second) Click one of your chat groups (~2 seconds)
This is merely just to show something
From what I have seen, its quite easy to have performance issues with React
Or are you implying that React does not fit FB use case?
Are you just going to defend React to the bitter end? Or do you just enjoy imaginary binary choices?
I don't defend React. My question was almost the opposite and I was trying to ask:
So if even Facebook has a problem with using React then who has a better examplea about why and how to use it?
Source: I work closely with him and have been frustrated with this stance until I saw people using Next and Remix for things like landing or contact pages.
This is not practical advice for the vast majority of software engineering teams.
Most teams do not have the privilege of being able to do research and prototypes across multiple options, at least in a way representative of what their final product will look like. Most teams - at least those in small to mid-size startups - will start out building A, route through A' and A'' and end up building B once they land on PMF. If you were to run 5 different prototypes on A, you're going to be a bit upset when you end up at A' and you're likely to run horribly technically aground when you truly find the right thing to build.
Yes, if at the point when you discover B you have the latitude to rewrite your entire codebase to fit your new criteria, then by all means, go ahead. That will definitely outperform React. I think the teams with that kind of latitude is an exceptionally small fraction of all teams, and the number of teams with the technical chops to do it correctly will be an even smaller fraction of that. The rest of us will use React, which is roughly 80% as good as the optimal solution.
To your point though - use the platform. Vanilla HTML, CSS, and JS. All of that will be reusable no matter where you pivot and not lock you in to a pattern that might not work well for where you land.
This is a non-answer. It only really is an admissible solution if you're just working by yourself. React solves real problems when building web applications. If you use vanilla HTML, CSS and JS, you're going to have to solve those same problems. How are you going to do it? How are you going to manage state? How are you going to synchronize your state with the DOM? How are you going to organize your components?
Teams that use vanilla HTML, CSS, and JS end up eventually building an internal, buggy, half-implemented, undocumented version of React.
I did find some recommendations for other reactive front-ends buried in the article, but I didn't see anything that set them apart aside from the fact that they are smaller projects. Now, if I want to follow the article's advice and get off of React I have a ton of research to do, research that the article's title didn't hint that I'd have to get going on.
Eg. There's a delay between an Amazon.ca results page loading and it populating the search text box with the phrase you just searched for. As a result when I do two searches in rapid succession, it consistently interrupts my typing at exactly the right time to batter in incomprehensible text.
AirCanada and WestJet are two other websites that became awful to use after adopting React-ey style UI's.
But one thing I've noticed is that because frontend code runs on users' computers, fewer businesses and engineers have the incentive to really optimize that performance. If one writes bad backend code, it shows up as increased AWS bill; if one writes bad frontend code, well the cost is diffuse and many don't notice it.
cool maybe I'll see one one day
> React gives you many tools to skip unnecessary work and reduce latency, such as shouldComponentUpdate, and assigning keys to elements in a collection
but do people use these outside of demos
I have an high end CPU with 32GB of RAM and almost every single website I use gives me a worse experience than I got 20 years ago
> if one writes bad frontend code, well the cost is diffuse and many don't notice it.
exactly, and that's why we are where we are today - surrounded on all sides by websites covered in glue, because bad experience has been completely normalised, all for what? Some abstract notion of developer convenience that results in almost every case in a significantly worse experience by almost any metric.
This is funny to me, because I would think that for hundreds of milliseconds, anything user-facing is impacted. It's on the order of the human reaction time (~200ms). That's noticeable delay.
I do not work in frontend, so perhaps I am misguided. But I have had bad user experience using apps with even 100ms delay that require a lot of input (for example using excel or something in a streaming VM).
You can totally shoot yourself in the foot with any language or framework. And you can most certainly do that with React as well. As we so often see.
I've never had a performance issue I couldn't fix in React.
What amount of performance issues you will not need to fix if you were not using React to begin with?
Many years ago I worked at a wonderful company that made the terrible decision to rebuild the frontend in React. We had a performance dashboard permanently displayed on a TV in the office, prominently showing the p99 time-to-interactive of our home page. It sat at TWENTY SECONDS for at least 2 years. No progress was ever made, to the best of my knowledge.
This was an e-commerce site, more or less. As per the author's reasoning, it absolutely should not have been an SPA.
The only client side component of interest would be filtering and sorting, (although the server could render the new state too). I would choose traditional server side + a little bit of client side code here.
The only reason any of the above sounds fine to take this long is because the standards of web development are so incredibly low.
The only reason that 100s of milliseconds might sound fine is because there are multiple layers of abstraction between levels, but as you can see from all the other responses here the 100s of milliseconds evidently does not sound fine.
This is not my experience on real react sites. Loading the pages on mobile (say 4G) takes seconds to load with a partially rendered page which is slowly constructed. Loading the equivalent pages in HTML rendered server side would reliably be under 100ms (excluding assets). This is somewhat disguised by better connections and large images taking up, but all that js and json does have a cost.
You're probably trying to talk about the overhead of the framework, but what is the true overhead of a framework which encourages you to introduce bloat and create a separate component file and sometimes a separate network connection for every single component on your web page?
Here is a real case study with comparison of approaches from this author: https://infrequently.org/2024/08/object-lesson/
>The second reason the author says is that it’s based on a legacy eventing system which supports IE.
There are lots of horrible bits of react which are based on solving problems which aren't really a problem on the web any more - from manipulating the dom (pretty easy without react) to dealing with IE polyfills, and lots of bits that you really don't need the client to concern itself with (i.e. routing code). You may not care about that code but you are importing it and forcing your users to download it. It all adds to overhead.
There are also a ton of other points in the article which you've elided, which go into the multiple failings of React as a tool, and primary among them is that it encourages you to use react and only react, the ultimate in lock-in.
> Finally, the author doesn’t actually give a prescription as to what to use instead of React.
You want them to choose one framework instead of react, they're explicitly rejecting that choice and saying you don't have to become a follower of react or any other religion, instead they're advocating choosing tools based on the evidence they have presented, so they are IMO presenting a clear choice:
Server side rendering with a bit of js as required to load dynamic data
React or similar frameworks which try to push everything to the client
I'm guessing you're one of those developers who never browses the web on anything but the latest Macbook Pro and iPhone. I implore you to restrict yourself to some lower end devices for a few weeks and let us know if you still feel the same way.
“Most sites” sit in the world of marketing, ecommerce, blogs. True, they don’t need an SPA.
Then there are businesses that “require” highly dynamic websites with tons of data funneling through them. I use require here in the sense of business requirements set by the various Product teams.
These products benefit from being an SPA. Preload and fetch is such an incredible paradigm for speed and interactivity that every company I’ve worked for has appreciated. Company employees are not trying to run their work browsers without JS nor do they even have to particularly worry about mobile support. It’s a very predictable environment: office, work laptop, internet that can support video calls, and a modern browser. That’s the operational stack that many businesses require.
> The predictable consequence are NPM-algamated bundles full of redundancies like core-js, lodash, underscore, polyfills for browsers that no longer exist, userland ECC libraries, moment.js, and a hundred other horrors.
People really love to hate on npm without trying to understand the reason why it exists in its current form: https://bower.sh/my-love-letter-to-front-end-web-development
As a semantic aside, I wince when people call React a framework. If we think of an SPA in terms of an MVC framework, it primarily handles the V. So really it’s a view library since developers can use whatever M and C they want. Next.js is a react framework and as a React expert it’s something I have zero interest in using.
I could keep going but these arguments have been argued and counter-argued before. For a different spin on the success of react: https://bower.sh/react-is-bad-because-its-great
It doesn’t have a great story for virtually anything outside of that single function which means for many large apps it is never enough.
No, I'm illustrating the limited scope of React. I wouldn't call a chunk of code that handles the V in MVC a framework.
> for which the definition is usually the calls into you/you call into it thing
Again there's nuance here:
import { useEffect, useState } from "react";
import { createRoot } from 'react-dom/client';
document.body.innerHTML = '<div id="app"></div>';
const root = createRoot(document.getElementById('app'));
root.render(<App />);
function App() {
const counter = useState(0);
useEffect(() => { console.log('effect') }, []);
return <h1>hello world: {counter}</h1>
}
I'm "calling into" react (3) times here, while react is calling "into me" (1) time. Are we saying any external source code that accepts a function as a parameter is considered a framework?All react does is render/diff/patch your dom, everything else is up to the end-developer. Would you call `express` a framework? Again this is semantics but look at all the react frameworks that exist on top of react, why do those exist?
It's calling into you three or more times, invisibly, if I remember the details of what useEffect and useState actually do at runtime correctly. Which rather illustrates the point.
> Are we saying any external source code that accepts a function as a parameter is considered a framework?
Code that accepts a function for narrowly scoped use where the control flow is still under your control (e.g. map/reduce/filter libraries) is probably not a framework. But external code where you register a callback that gets called some time later, not under your control, is pretty much the definition of a framework.
If they were using useState() correctly and provided a button or link to call the update function, yeah, React would call into their code as many times as the user clicked the button. As it is though, it's just once (useEffect with that second argument is "only run the passed-in function once on mount").
As I understand it both the useState and useEffect create points where their code will be suspended and resumed as a coroutine, even if everything only gets run once? But yeah, the more important point is that in the general case React will run it multiple times in ways that are not really under the user's control (at least not without understanding the internal details of React quite deeply).
The first run through, useState() returns the default value and your code runs to completion. When the update function is called, that entire React function is run again, but this time useState() returns the new value instead of the default value.
Likewise useEffect(), your React function runs all the way through and the callback passed to it is run afterwards at various times depending on the dependencies array. First run is immediately after, on component mount, then every time the dependencies change (if dependencies are specified), or every rerender (if null/undefined instead of an empty array).
Your function was still sliced into the part before and the continuation (Dispatch) after though, right? The React runtime calls that continuation immediately with the default value, so you don't notice the suspension, but control flow wise it's still React calling your code twice rather than once.
React isn't a library, it's a framework. A narrowly focused framework perhaps, but a framework nonetheless: it has to control the event loop and you have to follow its special rules (hooks), you can't just call into it like vanilla code.
I once was told to make a product "cool" and after struggling to understand what "cool" even meant, I came to an idea. Things are cool if they make it so you never see the world the same way again. react-three/{drei,fiber} and threejs are cool. [For example https://r3f.docs.pmnd.rs/getting-started/examples]
* x-platform (that was a big thing in jQuery in the beginning): solved in JS
* DOM selection (not as elegant w/o some aliassing, but still): solved in JS
* making XHR: solved in JS
* building plugins: solved in JS
* method().chaining().style().of().programming(): not in JS
That's mostly I think.
One reason for the mess seems to me is the coexistence of many paradigms for achieving similar functionality (for example you can draw many different boundaries between client and server).
Combine this with the many distinct use cases (form factors, application types etc.) and the various non-interoperable platforms and you have a serious combinatorial optimization problem.
Depending on what one wants to do there might be a sweet spot of the 80%/20% type. Alpine.js seems to one such, which if it was developed many years ago it may have saved a lot of wasted complexity.
It is well architected, yet only uses a 500-line component lib and a 500-line router.
People love complaining about React, but I don't know if they remember the pre-React world where you had to write the code to manage O(n^2) UI state transitions via recursive mutating callbacks. Simple things like "have a the list of photos shown always kept in sync with a label showning count of photos" was incredibly error prone, and the complexity of implementation went up quadratically with the complexity of your app (due to the n^2 state transitions you needed to worry about!)
Today React is not the only one to do this O(^2) to O(n) complexity reduction, but it was the first to go mainstream, and very much deserves its success in spite of its various shortcomings
With pre-react single page apps, if you had O(n) ways your webpage could display, you needed to write code to account for n^2 ways that each of those n states could transition into another one of those n states
With react, you write code to render n pages, and get the fine grained interactivity for free with good (enough) performance. It basically removed a tradeoff/dilemma that had been facing web developers since time immemorial, so no surprise it was a big hit
"A pure function which transforms the entire input into the entire output" is obviously the simplest possible architecture for many programs, but people hesitate to use that architecture because of performance concerns. In practice, the baseline performance is often faster than they expect, and it can be made much, much faster using strategies like memoisation and fine-grained reactivity.
We actually see similar innovations on the FP side as well, with persistent data structures that allow structural sharing so your "copy and update" operations can be fast enough to be usable (even if still not nearly as fast as in-place mutation)
Hooks are a declarative DSL for accumulator arguments to the recursive function (the component).
If you would rather rewrite the render loop in continuation passing style, and have a 46 line recursive call expression which conditionally changes like 15 immutable parameters to set up the next render iteration for your component, I'd like to see the code when you are done.
But before React came along, you just couldn't do this without major UX breaking bugs, because of how the DOM worked.
Say you have a form that you want to change depending on the state of the app. If the user is typing in a form field while an update to the app state comes, and a pure function that transforms (app state -> DOM/HTML output) resets the form (meaning removing the old out of state DOM and replacing it with the new DOM), the user loses focus on the form. So you have to add some kind of logic where the app remembers what form input the user was focused on, where in the field the focus was, etc. The more complex your app is, the more complex the DOM reset logic became, and you cannot abstract your way out of it with pure functions, because the DOM that relies on mutation slowly creeps into your pure functions anyway.
React changed this, because it gives you a pure function interface, but resets the DOM using mutation functions i.e. native DOM methods, surgically. This is achieved with the VDOM (Virtual DOM), by diffing VDOM states and then reflecting that to the actual DOM. This means when the DOM resets, there's no problem with elements getting removed and added back in, and the focus states etc. don't get thrown away with the DOM. Before React, nothing like this existed.
Could you give a practical example of what you mean here? I can't quite wrap my head around what kind of interaction you're describing.
Do you mean some kind of scenario like a shared document with multiple people editing it? This is a very niche case.
> This means when the DOM resets, there's no problem with elements getting removed and added back in,
Could you give a practical example of this? I've been building web apps for a long time and I don't know what "when the dom resets" means.
React solves this problem by building a virtual DOM, and then conservatively updating the actual DOM (sometimes just mutating individual HTML attributes!) so that this state is preserved.
If you don't use a framework you will probably end up building one, and it's not going to be as good as the existing options.
Note: you might say node 16 is old and I agree. I'd much rather be on 22. But since I can't get out of this dependency hell without days or weeks of work the projects have been stuck for years.
I will just say that any project that lasts that long will require maintenance work now and then. The issues you describe seem quite minor and are probably relatively easy to patch up. React provides code mods that do a lot of the heavy lifting, your external widgets have updates, or alternatives.
I would also add that you don’t have to use dependencies with react. It’s always good to be mindful of dependencies and limit them.
It’s the same thing, you choose dependencies to save you time, or you do it yourself.
My main point is that with your own framework you will also run into limitations, causing big rewrites taking days/weeks/months, and/or lots of upfront cost..
Does anyone remember a blog post from maybe 2016-ish which described the process of "building your own" react-like rendering loop? I remember it being a fantastic explanation of what the virtual dom is and does, and why the "UI is a function of state" paradigm is great. I remember it having a live example to the right side, with prose and code on the left. I can't for the life of me find it now :(
I remember the article very much taking the approach that you've never heard of React before, and walking through a series of problems and discoveries like "oh, what if we just render the state to the DOM every frame? let's see how that works".
Almost like a "you could have invented React" kind of vibe. I think there was a button-counter demo app.
https://web.archive.org/web/20150414080539/http://hackflow.c...
- https://archive.jlongster.com/Removing-User-Interface-Comple...
https://youtu.be/bhvNvQA2oqA?si=bJYZYAU8uueb-6ST
And here’s a more advanced example that preserves input field focus and uses a context: https://github.com/jsebrech/vanilla-context-and-reducer
I really wish these people would pick up a history book. Unlike back-end developers, whose worth is intrinsically recognized as necessary, front-end development was lowly micro-managed job that must simultaneously keep up with customer expectations in a variety of formats while also rendering whatever slop passes for a REST API. React’s adoption was a combination of talented marketing and a genuine empathy for the frustrations of a 2010s web developer. They gave us a white-lie to pitch the idea to our managers: “It’s just the ‘V’ in ‘MVC’!”
JSX freed us from the jQuery-Rails template spaghetti. A quiet revolution soon followed and everyone’s been butthurt ever since.
Look — Server-side templates, especially the “stringly” typed variety, are a demonic chimera suitable only for depraved alchemists. There’s no type-safety, no IDE references. You’re in Hokey Pokey Hell — we start with a string, now we’re interpolating, back again, now once more deeper and let’s really put your editor’s syntax highlighter to the test!
It’s no surprise that stringly typed tools like HTMX and Tailwind are so deeply admired by mid-career developers who are frustrated by their lack of experience and eager to prove their talent. That’s all very normal and healthy, but the problem isn’t that React is too complex. Building software as team is a complex task of communication, and pretending to be illiterate doesn’t make the hard words any less difficult to read.
There’s most definitely room for improvement in React, and the team at Svelte demonstrated that you could have your state and skip the boilerplate too. Svelte’s compiler is a genius move and unfortunately for them, React’s upcoming v19 will commodify their complement.
It’s never been about replacing React — it’s about empathizing with developers and making it easier to work together.
Wanting to prove yourself isn’t a problem. It’s actually a sign that a developer is starting to form their own opinions. But it becomes toxic when the primary motivation comes from a desire to appear smart instead of actually solving a problem.
You’re absolutely right about typed classes and that’s how React Native does it. Writing and debugging CSS is hard for many of the same reasons that string-based templates exhibit. IMO the developers who push Tailwind are looking through the wrong end of the telescope. CSS is challenging because it’s a combination of declarative aesthetic UI and imperative state management. Choosing to represent that complexity with Tailwind guarantees what could have be a temporary ignorance into a more permanent crutch that retains the same faults of the underlying abstraction, tragically opting out of any of the benefits of embracing the system. Modern CSS is pretty great and learning how it works pays endless dividends.
I think you maybe don't understand what Tailwind actually does. The only abstraction is its "language" that is used to generate the list of class names you can then use to style elements, but that's not really an abstraction, because in the end it's not that different from using something like BEM and then having to remember project-specific classes. But with Tailwind, it's not specific to a single project. And you always have to understand CSS and how it works anyway.
I couldn't agree more with this. Components and TSX are a much nicer way to build UI trees, even on the backend.
Over the years, I'm seeing more and more unlearning of fundamental web from new frontend devs forged in boot camps.
On the other hand, with something like react-router you can now just download the full page content[2] but without <head> [3], and then make the browser re-draw only the parts that changed.
Only half-joking though. People can build things whatever way they like, and these frameworks can have good trade-offs. But sometimes the justifications devs give[4] just sound like they're reluctant to say "because I already know it, so I'm more efficient with it" or something like that.
[1]: "Paint holding".
[2]: Code splitting.
[3]: These savings are probably offset by the library's 19kB, anyway. Or with that small icon that was inlined as base64.
[4]: Which they don't need to give to anyone, unless it's for a situation like an employer asking for it.
As far as I can tell, React let's you write HTML in both the right and wrong ways, like all frameworks (including plain JS).
Maybe it seems like React is worse in terms of HTML because of how popular it is? There are more users of it, so more potential examples of bad HTML?
I think you have hit the nail on the head.
React can use links and still be dynamic. The problem is without it, you break the browser history, you break long press menu on mobile, you lose the link preview in the status bar.
Also, website aren't slow because of React, they are slow because of shitty developers or insufficient budgets.
A tool like React can shrink the space you need to be vigilant about to ensure performance (not just speed but also UX), but you still need vigilance and attention to detail to make sure you're not making mistakes like running something on every re-render that you meant to do just once.
And it has its own idiosyncrasies that you need to be vigilant about. Like if you write a hook `const x = useMyHook({ optionA, optionB })` then you need to handle the cases (either at the call site or inside the hook) where the options object is new one every render and when optionA or optionB are non-primitives that change every render.
It's because when you write code using these libraries, your code looks nice.
I cannot say that for a LOT of libraries, especially MOST frameworks. Sorry for calling AngularJS out but look at a code sample from early Angular: https://stackoverflow.com/questions/42823436/angularjs-error... (It looks terrible.)
React will be unseated like jQuery got unseated when someone makes something that looks nicer. Every time you write a library (or even API at work), make sure to look at your code samples and you better be 100% be able to say "this is pretty."
Pretty definitely does not mean readable.
That said, I think client side UI/UX is about to see yet another large wave of change. Hearing chats from solidjs devs make me feel that there's a whole new and saner space to describe simple and fast programmable interactions.
In fact the "write a component" part is the center of React but only one of the features of Angular. In my experience, the big advantage of Angular is that you rarely need anything else and so it’s totally possible and reasonable to write a full fledged application without any other dependency than Angular itself. In $prev_job, we had nothing else in package.json than angular, some internal libs and the internal design system (which were exposed as angular providers) and some wysiwyg editor like quill.
It’s far from the funniest framework, but for writing boring things in team setting, it’s actually pretty good.
In fact having worked on the oldest AngularJS framework, it’s very interesting how it made a full 180 from "magic everywhere" to a boring "enterprise" framework.
I would never make a side project in angular because it can be pretty boilerplatey but in a team of 3 or more devs in a multi months dev project that I’ll have to maintain for years, that’d be my choice.
Except if I can reasonably do it without an SPA beforehand but that’s a totally inaudible proposition in corporate world anyway.
Clumsy and hard to learn ? Sure. The code looking less cool than other frameworks ? Of course. Unbearably slow compiler ? Check.
But at least you got a full fledged, batteries included framework, with a powerful DI system and an established architecture to follow. Not the funniest framework but it works.
The only powerful thing but also big flaw with angular is that they deliberately expose a lot of the framework internals with a very neutral documentation that never explains that you shouldn’t touch this or this in most cases. It allows very nice and clean extensions of the framework but, oh my, if you inherit a codebase from a "smart guy" who knows the framework inside and out and "did better" than the boring angular architecture, then good luck.
I know this can happen in any codebase and I’ve seen it everywhere but Angular exposes so much things that you can make horrible things.
But in a team who have a boring CRM or SaaS front end it’s a pretty good framework to use. Except if you can do everything server side.
yeah, that's worthy, especially in teams, it avoids friction most of the time
When you use an operating system, you don't see the millions of lines of code that go into scheduling/kernel, drivers, etc.
The solution is WebAssembly. Make your code look as nice as you want, as readable as you want, in whatever language you want.
No more JavaScript limitations.
I wonder how much would WebAssembly suffer from this and compatibility issues. I hope browsers to improve WASM ecosystem so that it can be used more widely and without the need to ship the whole runtime with your website.
[1]: https://world.hey.com/dhh/turbo-8-is-dropping-typescript-701...
But you accept a whole host of other limitations with WASM. It's a trade-off. You still need to access the DOM, which can't be done directly from WASM. Maybe someday it will happen? Okay, so use canvas instead and do all UI inside WASM? That seems like reinventing the wheel that is Javascript + DOM. WASM has plenty of uses, but replacing Javascript probably isn't where it shines. Javascript is still great for front-end tasks, WASM is good for lots of other things that aren't user-interface related, like running ffmpeg inside the browser. I'm doing this on a project and the front-end was easy to create a drag-and-drop file upload in javascript (React) and handle all user interface stuff like progress bars, etc. ffmpeg runs as WASM code doing whatever the Javascript tells it to do. I can't imagine also writing a front-end in Rust or something else that's supposed to run inside a web browser in WASM just because of vague "JavaScript limitations", when Javascript is really a good solution for front-end UI inside a web browser.
You can access the DOM through JavaScript glue. These Rust WASM frameworks do that:
- Leptos: https://www.leptos.dev/
- Sycamore: https://sycamore.dev/
- Yew: https://yew.rs/
- Dioxus: https://dioxuslabs.com/
Eventually you won't need the glue.
> Okay, so use canvas instead and do all UI inside WASM?
You can do that too. That's what this VB6 clone written in C# and compiled to WebAssembly does:
- https://bandysc.github.io/AvaloniaVisualBasic6/
- https://github.com/BAndysc/AvaloniaVisualBasic6
> vague "JavaScript limitations"
It's not vague. Despite 28 years of effort optimizing JavaScript, WebAssembly outperforms it:
- https://nuenki.app/blog/bloom_filters_optimisation
- https://jordaneldredge.com/blog/speeding-up-winamps-music-vi...
- https://www.amazon.science/blog/how-prime-video-updates-its-...
- https://web.dev/case-studies/google-sheets-wasmgc
That's a kick to the groin that's tough to walk off.
That's great that WebAssembly outperforms Javascript. But only in processing power - and not all programming tasks require the most bleeding-edge performance. User interfaces do not require the speed of WASM. They require being easy to develop, and Javascript is almost always the right solution for UI. None of the WASM frameworks you mentioned are used very much, there's simply not the ecosystem for them that there is for Javascript for user interfaces.
And this is what they mean when they say "use the right tool for the job". I'm not going to use ffmpeg ported to Javascript, because that would be slow - of course I'm going to use ffmpeg in WASM to transcode video in the browser. And I'm not going to replace React with something in WebAssembly no matter what language, because it's just far easier to write the UI in React. Or even jQuery, or even just plain old vanilla Javascript.
Javascript is a very easy language to work with, in spite of what the people that don't really understand Javascript think about it. The only reason to do UI in WASM is that you don't understand Javascript or you have an irrational hate for it, or "because reasons". But sure, do whatever you want to do, I'm in no way saying you can't. Just don't expect that WASM will be replacing Javascript in any real way, anytime soon.
Only in processing power?
So you mean JavaScript is less efficient than WebAssembly, which means every time a piece of JavaScript runs on the billions of systems running its suboptimal runtime there is higher power usage, which means there is a greater demand on energy supply, which means there are greater carbon emissions, which means more global warming, which means we're closer to a climate change catastrophe than ever before.
So not only is JavaScript slow it's also an ecological disaster.
You've convinced me. Brendan Eich has a lot to answer for.
Slow scripting languages don't make you eco.
You have to think bigger.
oh, oh, wait - I have an idea! Let's just write everything in 8-bit assembly language, that will let us really optimize and save all the electrons for bitcoin mining! /s
You really are barking up the wrong tree. Going after Javascript as if it's the reason the planet is doomed, or even makes any difference at all in the grand scheme of things, is just looney tunes crazy. Sorry, it just is.
Don’t tell me “whatever language you want” means “whatever language named Rust you want”, thank you.
OK and then how do I do my form UI on that codebase?
When at all possible I write stuff in Scala, using Scala.js when it needs to run in the browser. But I still use React for the UI part.
But I realized that actually supports your argument. React with Hooks and functional components unseated old school React.
Is this a widely held opinion? Call me crazy, but I really liked class components. It was nice to see the lifecycle stages in the actual method names, and encapsulate the behavior inside of a method block. To me that was really nice to read.
With hooks, everything is inside a function without clear delineation. The lifecycle stages are put anywhere in there with (to me) strange looking calls to useEffect and such.
Before, I used to love whipping up a quick UI in React, but since hooks I loathe doing that. I really don't want to upgrade my existing apps to newer versions. And for potential future project I'm looking for an alternative.
Perhaps I don't like it so much because I'm primarily a back and systems engineer, and only do small frontends on the side.
Anyway I think react in general is kind of terrible. I’ve worked at three places whereFE teams made a react codebase that wound up being so scary and difficult to work in that essentially no one would touch it, until it eventually got rewritten. Two of those just rewrote it in react again, hoping that whatever faddish state library would save them from themselves. At the third, they rewrote it in svelte, which went much better. At least for me as someone who only writes FE code when I have to, svelte is much more comprehensible and sensible.
For similar reasons, I thought Vue.js would win over React, but it's starting to seem I was wrong.
My feeling is that the core issues were never really addressed. Javascript was utter shit 25 years ago and it still is. CSS was an inflexible complex mess. And it still is. And the browser's DOM tree was more or less an accident that resulted from a brief industry wide obsession with things like XML. Hacking UI frameworks on top of that is basically what most frameworks do. But it's just not a very good basis for any of that. Design by committee stuff. All of it. The worst is that there's a lot of good UI out there on other platforms.
The web was awkward and painful 25 years ago and it has gotten a bit better but actually not a whole lot. There's nothing pretty about it. Or state of the art (not even close). It's just a lot of mediocrity and a culture of people confusing this mediocrity with "apparently this is how it's done" and not even questioning it anymore. It was easier to do some things with Flash twenty years ago than it is with web technologies today. People have stopped bothering to attempt to even do a lot of these things. Just not worth the pain. And mediocre is good enough. Slap a drop shadow on it and call it a day. Maybe a cheesy css transition here and there.
I love brutalist websites like HN calling bullshit on this crap. Dang and his friends don't even attempt to dress it up. It's orange! Forever! Enjoy. It looked dated ten years ago, the same it does now. But it's also a major news website running circles around most of its competition. At best they might weak 1 CSS color around Christmas or so from orange to red. That's about the extent of "web design" that happens on this website. It doesn't need it. It would be just window dressing.
All these arguments about frameworks and libraries would be moot if the web technologies were properly designed, so i believe that is where we should focus our energies.
Why is it that after several decades HTML, CSS and JS are still so primitive?
If I've ever come close to something like a natural law in software development, it's Conway's law. Therefore, this strikes me as saying: Design your airplane according to what the pilot needs, not aerodynamics or gravity.
GridWhale runs your code entirely on the server and then remotes the UI to the browser via a platform layer.
The advantage is that you can program a web app as if it were an old-style GUI app on a PC: your program has full and direct control over the UI. For example, imagine you need to disable a button due to permissions. In GridWhale, you just check the permissions and set .disabled = true on the control. This automatically propagates the setting to the UI. And because the .disabled property is on the server, it stays disabled even if you hack the client.
In contrast, with React or any framework-based UI, you need to write code in two places: on the server (at the API level) and on the client to show the proper UI. And if you're not careful, these two can get out of sync.
Of course, GridWhale is just a different trade-off. It works great for traditional business apps, but would not be appropriate for low-latency video games (at least not yet).
Something not JS, or even TS. So it has to compile to JS or WASM or both.
Rust is cool. Dioxus looks really promising. https://dioxuslabs.com/
Elm is great. Actually quite mature in my experience. (Sure there are talks about the development model and release cadence, but still...)
Same $LANG as on the backend, as many langs compile to JS and/or WASM nowadays. But then how do you feed the browser a DOM? You still need something: HTMX, or... React?
And if you squint your eyes, isn't Elm also doing the DOM-feeding in a React-like manner? (I dont know for Dioxus).
Possibly the idea of React is really good, just Elm has implemented nicer? (and provides a good story for how to structure the rest of the application: state-mgmt, API calling, etc.
And Leptos: https://www.leptos.dev/
And Sycamore: https://sycamore.dev/
And Yew: https://yew.rs/
Unfortunately, it seems essentially impossible to get get traction in my country so I'm unsure what to do with it. I use it for my own projects. See https://saasufy.com/
I'm inclined to think this is one of the areas that GenAI can massively reduce cost. Claude will even iterate wireframes (in React).
As for performance, that's not going to ever be a framework problem. That's a deployment and scaling and architecture problem.
Blazor static rendering provides a great UX for rendering static content, Streaming Rendering is great for pages that needing to dynamically update and any pages requiring client interactivity I just progressively enhance Blazor's static content with Vue - avoiding any npm node_modules dependencies or client build tools.
While it _can_ be super fast, in practice, it requires quite advanced knowledge of React-isms to get it there. Those React-isms require more code with increasing complexity, combine that with contributions from developers that have varying levels of experience and you end up with spaghetti code.
Consequently, I have yet to walk into a new role where the React code isn't a dumpster fire.
In a way, React feels very much like writing raw C - it has a lot of power to be fast but most developers aren't as smart as you (joking, sarcasm) so unless you're the only contributor; you're better off using a higher level language with fewer footguns.
Modern Angular, for instance, is amazingly ergonomic and the opinionated approach makes it difficult to drag the project too far down the unmaintainable rabbit hole. The compiler handles optimizations for you so you don't need to worry about render cycles or how a functional component loops around - making it friendly (in theory) to developers with varying levels of experience.
These ergonomics fall apart when developers try to make Angular projects "React-y" with tools like ngrx but for me; the biggest downside is that you have no control over the tooling (test runner, TypeScript version, bundler, etc). That is the only reason I avoid it in personal projects.
Svelte and Vue on the other hand suffer from similar problems in that they are fantastically ergonomic, but use custom file formats with bespoke compilers that are difficult to integrate with other established tools (TypeScript, linting, formatting, testing).
One thing that saddens me is that toolmakers (specifically TypeScript) sleep on opportunities to have much better front end frameworks because they don't provide the capability to extend the LSP and transpiler.
For instance the inclusion of Rust-like compiler macros in TypeScript could enable projects like Vue, Svelte and Angular to integrate directly into the language without the need for bespoke compilers and adapters to connect to tooling.
That way, much like how TypeScript has a built in compiler for JSX, Vue could integrate their template compiler within TypeScript rather than using external tooling that targets .vue files - example:
export const HelloComponent = {
tag: 'app-hello',
template: vue!(<div>Hello {{name}})</div>),
data: () => ({
name: "World"
})
}
And Angular class AppComponent {
static tag = 'app-component'
static template = angular!(<div>Hello {{ name }}</div>)
#[model]
name = 'world'
}
Alternatively, the completion of wasm would enable the use of languages with the appropriate feature-set required to build maintainable, multi-threaded & performant web applications - but at this point that seems like a distant pipe dream.So ultimately, while React isn't really a great choice for web applications, it's attained a jquery-like status where it's not really good but the alternatives are worse so you kinda have to use it.
It lets you write your frontend and backend code in the same language, even sharing models and validation logic so refactorings work full stack.
You get strong typing and a rich SPA framework that includes routing, templates, and easy server calls.
There's a book ( https://frequal.com/Flavour/book.html ) and a Java SwingSet-like app with live demos and source code called Tea Sampler ( https://frequal.com/tea-sampler/ ).
While frameworkism has bad sides, React (hooks) is bad in very unique and particular ways, sometimes switching a different tool is the answer.
Any engineer who thinks that its React that is causing the slow renders and replacing it with X is deluded. Yes, there are ways to make slow React web apps. But there are also ways to make fast React web apps. It just requires effort and a little bit of foresight.
A hybrid approach of server-side views with a simple lib like AlpineJS or HTMX for dynamic bits is far better in most cases. The initial page load is blazing fast because the server does the work. Then, for things like filtering or updating lists, you use the lightweight library for smooth, efficient updates. You get the best of both worlds—a super-fast initial experience and the ability to add dynamic features without the React baggage (and often-neglected backend).
Fortunately there has been some change in this area. FastHTML is a batteries-included library for Python and there are numerous standalone HTML generation libraries that can be used with other frameworks like Django, e.g. htpy, htmy etc.
I've been using alpine on a static site and it's really quite impressive just how much of "the stuff you probably want js for" it covers. So much so that you can pretty much say "if you can't do it in alpine, maybe we shouldn't do it at all".
Then you can just add Alpine as necessary.
Indeed, if your needs are more static, a SPA is probably not a good solution. But if you really do need a SPA, React is a sensible choice and can perform well assuming good engineering.
Everything is a trade-off, and SPAs offer a trade-off that is right for some cases and wrong for others.
There are multiple possible solutions to most problems, including gmail or google maps for example. Just because you want to load code and data dynamically doesn’t mean you need to buy into SPAs (the followers of which I’d argue are far more fundamentalist in insisting you can only use SPAs).
I disagree with that too. Did I ever say otherwise?
I do believe, however, that there are problems for which a SPA offers the best trade-off. Not the only solution, but the best trade-off.
> This is an orthodoxy which people buy into but there are always a few different approaches possible.
Like the orthodoxy that "nobody needs an SPA"?
> What do SPAs actually offer which is unique?
Interactivity. Good luck keeping your focus or scroll position while reloading a page. If done carefully, performance can also be on that list, though I agree it is often not done carefully.
> Just because you want to load code and data dynamically doesn’t mean you need to buy into SPAs
Agreed. Though you can load both code and data dynamically from a SPA, if you need.
Perhaps our definitions of a "SPA" differ? SPA is when you don't do reloads, hence "single page". But there are many ways to do that, some of them involving React.
React solves problems we don’t have any more (eg IE), badly, at the cost of poor performance, lock-in and a host of other problems that other solutions just don’t have.
It means downloading MBs of javascript just to render a simple page.
It encourages multiple loads of massive json payloads for bits of the page which are then translated into html; this is a huge complexity and network tax for no gain.
It encourages constant re-rendering of page components.
It encourages mixing code and layout, making it incredibly easy for junior developers to make a terrible mess.
It encourages splitting web pages into thousands of components with poorly defined boundaries and putting lots of logic on the front end - this is disastrous for productivity and clarity when the project is of any size.
It has a bunch of legacy bits (double rendering, useEffect, useMemo, shadow dom etc) which just aren’t required and are often solutions to problems react itself created.
As to a prescription for what to use instead of react - anything else which is not ‘modern javascript’ would be a good place to start. Start with server side rendering and stateless web pages, add interactivity and dynamic loading as required.
The original motivation was to describe UI as a function of state. It sounds trivial, because it is when server rendering, but once you start sprinkling enough interactivity it can get messy. It's of course not the solution to everything, but above a certain level of complexity I really think you should let someone else handle the problem of syncing state with UI, and JS on its own will never do that for you.
Re the original purpose of react being syncing state, I’m really not sure this small problem is actually worth the trade-offs of massive complexity and lock-in, nor that react is a good solution for it (double renders, persistent rendering bugs, use state, hooks etc).
It’s not something important to lots of apps and there are loads of other options from simple polling to web sockets to reloads, this can be done in a far simpler way without react. Also the use cases where this is central are really quite small.
React + react-dom minified gzipped is around 60kB. Yes, this is a lot; but no, this is not MBs of javascript. If your (simple) pages download MBs of javascript, that means you have added lots of other stuff on top of react.
While I completely agree that react is unnecessary for simple sites, react itself is not guilty of megabyte-size javascript bundles.
Why not just drop the requirement altogether? All I want is an internet of links, images and texts? Whats so wrong with Facebook that looks like this website? Just a bunch of links and texts.
I don't give a shit if the button is a square or round. Why do you get to decide what is "best" for me anyway? Let the web be the web and the user decide how to present them.
"It isn't React, just those specific implementations"
Perhaps it is React, JS ecosystems and overbloated frameworks generally. These tools provide abundant footguns.
I've come to the realization that unless you're OK with some very clunky front-end, there's just no way to avoid quite a bit of JavaScript on the client. Once you need to write a non-trivial UI heavy web app, you quickly realize that avoiding JavaScript on the client is a non-starter, as cool as that would have been.
The issues involve a lack of standardized sophistication of the web technologies, like HTML controls being clunky, very unsophisticated and hard to configure/style properly, CSS not being properly composable, HTML forms not implementing the full set of HTTP verbs, etc... To me these are fundamental problems with the web architecture that need solving.
Revamping the web architecture to properly support a sophisticated negotiation of control between the developer, the browser, and the end-user would greatly reduce, if not almost eliminate, all the thorny problems that declarative UI frameworks and libraries bring into focus.
There's bloat and then there's sending the exact same thing over the network quadrillions of times at every page load because it's not standard and everyone needs it.
- Form is hard. Doing it in backend make it even harder when the form is complicated. For example, a form with tab needs JS to operate and you need to signal the JS which tab the error is.
- If you're using backend form framework, you don't have control over the HTML unless you learn the hook points of it (do you add attribute in code, or in template? Where is the default template to override?) Compared to frontend framework where you can paste the CSS framework's example HTML.
- I wanted to build a new user wizard, which should be easy with a frontend framework as you can easily store incomplete state in memory. If not using JavaScript one would have to store the state in the untyped session variables, add hooks cluttering the HTML template, etc.
- Progressive enhancement is easier when you have to write the code only once. If there's a table and you want to refresh without refreshing the page, in React you just call the data fetcher again. In HTMX your backend needs to have a "full render" endpoint and a "table only" render endpoint. If you're using jQuery you might as well write the table loop twice in the backend template engine and in jQuery.
- I haven't see any good backend framework (be it Django, Laravel, Symfony, Gin) that has similar server-rendered frontend component like React. Many frameworks believed that logic should be precomputed in the view layer and the template engine should not be turing-complete.
I was thinking about moving to SSR-rendered SPA, but I know of no Next.js-style library for any frontend framework that actually allow form submission without JavaScript AND progressive enhancement with JavaScript using the same code.
Yes, this use case is better solved client-side but even in an SSR app you can always use rich widgets/web components in React, Preact, Vue, Svelte, etc.
> I wanted to build a new user wizard
Use some JS component(s) or web component(s) as I pointed out earlier.
> In HTMX your backend needs to have a "full render" endpoint and a "table only" render endpoint
See fragments:
https://htmx.org/essays/template-fragments/
> I haven't see any good backend framework that has similar server-rendered frontend component like React
Plenty of backend solutions give you SSR components that are composable and where you can colocate template with backend logic. See Razor pages in dotnet or Astro.
> but I know of no Next.js-style library for any frontend framework that actually allow form submission without JavaScript AND progressive enhancement with JavaScript using the same code
I'm 99% certain SvelteKit and Remix allow you to do this.
Seems the author recommended HTMX as an alternative in a couple of scenarios including my own use case (https://caption.me).
I checked out HTMX. The canonical example on the homepage (https://htmx.org/) was a button where a click calls the server and the response contains HTML to replace the outerHTML of the button.
I must be missing something here. Is HTMX really suggesting muddying the back-end code with front end code? So, any changes to front- or back-end would have to be carefully managed to avoid breaking the other side?
Feels like PHP all over again!
https://htmx.org/essays/a-real-world-react-to-htmx-port/
looking at caption.me, I see nothing that couldn't be effectively addressed using this hypermedia approach, and I suspect it would simplify the application. You don't worry about "breaking the other side" because there is no other side: everything is hypermedia, in the original mode of the web
I don't think PHP has much to do with htmx: you can use PHP if you'd like on the server side, but you can use whatever server side technology you'd like to produce HTML. People are using Go, Java, Kotlin, Scala, Rust, Python, Lisp, etc. with it and it works fine. It's a generalization of hypermedia controls[1] (anchors and forms) and, like anchors and forms, has no opinion on what the server side looks like.
One piece of good news regarding htmx is that the API is not going to change dramatically in perpetuity, so there is no treadmill to keep up with.
HTMX components are 1:1 coupled with back-end code. So if I try to build a complex UI with nested structures, I'm going to have to build a parallel structure in back end.
The back end will have to manage all state, so there will be round trips for everything and things in server side memory that could be managed easily on the client side. That would affect the scalability and maintainability.
I'm not getting a sense of why HTMX would be better than a pure client/server approach. I have no attachment to "hypermedia," or any other concepts penned in the 1960s!
A complex UI with nested structures covers a lot of area: the DOM is fundamentally a complex UI with nested structures. I'd need more specific examples to say anything intelligent about it.
htmx certainly doesn't necessitate round-trips for everything. HTML itself doesn't (see detail elements and HTML5 form validations) and client-side scripting is perfectly compatible with htmx:
https://hypermedia.systems/client-side-scripting/
htmx is better than a pure client/server approach in some cases because it relies on the already-built hypermedia client, the browser. This can, in some cases, dramatically simplify & improve applications:
https://htmx.org/essays/a-real-world-react-to-htmx-port/
(67% reduction in LoC, 96% reduction in dependencies, halved memory usage, 50% decrease in first load time)
Looking at your application, it appears to be amenable to the hypermedia approach, but I didn't do a deep dive on it. OTOH of course, if you are happy with the current approach I don't see any reason to move to hypermedia for its own sake.