Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The self-fulfilling prophecy of React (joshcollinsworth.com)
172 points by rzk on Sept 8, 2022 | hide | past | favorite | 309 comments


I think the reason this article is wrong is this. The author says that React isn't the best in any singular category, and is solidly middle of the pack. But that actually makes sense; being best at one thing (such as bundle size) means you're probably making some tradeoff against another thing (such as functionality).

React isn't as fast as Svelte, but Svelte gets those gains by putting another compiler in your build pipeline, a tradeoff unacceptable to many.

React isn't as thin as Preact (or whatever other small library there is), but that means that React has more functionality.

React might not be as easy to learn as some other frameworks, but that's because, honestly, React chose the right abstractions to build, and those aren't always the easiest to understand. (Honestly, they aren't hard to understand either; it's a minor difference at most, but it is what it is.)

And honestly, if you were to build a big matrix of frameworks graded across all these categories, I suspect you'd find that leaders in one category almost invariably tank in other categories, for the exact reason that you have to make significant cutbacks in order to beat the tradeoffs that React made.


I'm not convinced.

In programming language / library design, you can often "have your cake and eat it too" if you can find a better design. Better designs take years to invent and mature - jQuery came out in 2006. React came out in 2013 (7 years later) and I think it improved on jQuery in just about every way.

But now its 2022. Its been 9 years since React came out. As far as I can tell, clever folks have improved on how react works in just about every way in turn.

What deep tradeoffs are Solid or Svelte making in exchange for their speed? I can't spot any. As far as I can tell, React's virtual DOM diffing is pure overhead - so good riddance. Solid and Svelte use a different approach to deal with state (similar to React's hooks) that honestly I prefer anyway. Dealing with state in react is a mess.

Where do the new frameworks lose to React on any technical metric? Svelte is designed to be compiled, but lets be honest - in 2022 almost everyone is compiling our JS anyway.

Go ahead and build a matrix of frameworks if you want. The competition is fierce. Like jQuery before it, React hasn't aged well. I'd bet good money that react, like jQuery, doesn't come out on top.


> Like jQuery before it, React hasn't aged well.

jQuery has aged beautifully!

In case you or anyone else reading don’t realize it, jQuery aged so beautifully the APIs are now built into (or in many cases fixed/standardized in) every browser in C++.

Yes that means the downloadable version is no longer needed, but please keep in mind every time you use a selector (for those that don’t call them “selectors” anymore some basic examples: “#content” or “.dropdown”) in JavaScript, you’re “using jQuery”. Even the fetch API was roughly pioneered by jQuery’s Ajax helpers, and slightly refined and included in every modern browser.

To discredit jQuery for being redundant is exclusively a lack of knowing browser history.


Id also add that Jquery's principle of simplifying and making JS accessible is legendary. A junior with a few weeks of Jquery can jump on a legacy codebase without much apprehension.


This is a great comment!


Thanks for making the record right!


Not to mention in 2022 jQuery is STILL pretty useful and relevant.


> What deep tradeoffs are Solid or Svelte making in exchange for their speed?

For Svelte, the comment you replied to already said that:

> Svelte gets those gains by putting another compiler in your build pipeline, a tradeoff unacceptable to many.

To emphasise, this was also the reason why it took so long for it to get TypeScript support (and I'm still not sure if everything's properly typed now, which is a common problem with template-based languages, but let's assume it is).

Additionally, I think (but haven't worked with Svelte, so could be wrong) that Svelte is a lot harder to write unit tests for? As in, you can just use React's virtual DOM in Node without needing to spin up a browser. With a quick glance I don't see any references to testing in the Svelte docs.

Solid I'm less familiar with, but AFAIK its architecture requires you to put logic back into your templates again, with components like <For>, <Switch> and <Match>, presumably limiting what you can do. And I totally get that the advantages of Solid's architecture make that worth it, but usually, if you can't spot trade-offs in advance, the reason is that you'll run into them later, rather than that there aren't any. So I'm sure I'd find more if I were to actually work with either of these frameworks. And yet I might then still conclude that they're worth it!


I find the granular reactive paradigm of Solid to be both harder to build composable pieces with, and harder to debug in a few ways. Having a render function that re-runs on updates where you can set a debugger or log is a massive thing.

Svelte has a whole host of similar and differing problems.

Personal opinion - I’d choose React today over the rest, as someone who built my own frameworks much like Svelte and Solid 5+ years ago.


I feel React has similar problems as Python, it was here first and thus it has become too ingrained in the culture, too many things were built on top of it. It will take a long time before something comes along that will de-throne them and even then you'll still see a lot of demand for devs who know it because there is too many codebases that people don't want to re-write. I don't think you can say the same thing for jQuery because first of all you couldn't build the same things with it and if you tried you probably hated it enough that you would jump at the chance to re-write your project with something like React.


> it has become too ingrained in the culture, too many things were built on top of it. It will take a long time before something comes along that will de-throne them

The reality is that nobody cares what you use to make your webpage or app. It might take a while to dethrone python and react, but who cares? Make software using whatever tools you want. There's lots of jobs, and these things are super easy to learn anyway.

I'm convinced that half of the jobs listing React are using Svelte or Vue or something, but know they'll get more candidates applying if they hire for react and then just train the person in vue after they start.


> I'm convinced that half of the jobs listing React are using Svelte or Vue or something, but know they'll get more candidates applying if they hire for react and then just train the person in vue after they start.

Easy to convince yourself of this, but in reality what is the benefit of having to sift through even more applications and waste time to go through the processes just to say "oh by the way we don't use React, we actually use Vue, hope that's ok" and think that the candidate, expecting to be hired to do React will just be like "yeah sure no problem, I actually mastered all the frameworks so it's fine that you lied about what you use."

Fantasy land.


You're framing "benefit" as it relates to the hiring process. The main benefit of a better framework or tool is that its a better tool.

But as for your points in hiring -

First, there's no need to lie on a job posting. "We use Vue, but we'll hire people with no vue experience. Show us your react chops and we'll train you up".

Doing something like this will get you fewer, but better candidates. If I see a job posting looking for frontend devs where they use SolidJS, I know the team isn't just a feature factory. They're interested and invested in the search for better ways of working. And I know they're given leave to do so by management. Thats a great sign for a good working culture. And from the other side, the kind of people who apply to jobs like that are the sort of people who don't see programming as a 9-5 grind.

I've seen this play itself out a bunch of times. At a startup I worked at many years ago, we took a chance and built our own data pipeline on top of Operational Transform. So all user data was updated live, character by character in our frontend app. It was really cool tech. We worried it'd hurt our ability to hire but it did exactly the opposite. We ended up putting it front and center in our job ads because high quality applicants were super excited by the opportunity to work on cool technology.


Let's be fair to jQuery: it has served its actual purpose well, and was a huge influence on modern browser APIs, thus making itself redundant. React and jQuery were never competitors.


The same is true of react. Modern web frameworks ooze with lessons learned from React’s design.


jQuery and React are apples and oranges. React was more part of a paradigm shift than a better jQuery.


I agree with you. The paradigm shift is from imperative programming, jQuery, to declarative programming, React. Completely different ways of reasoning about code.


Mixing HTML and JS is also novel to me. I’ve always been taught to separate concerns, only to find myself browsing files all the time. Mixing JSX and JS the sane way makes me feel 20 years younger.

It’s kind of like webcomponents (separate concerns by component, not by language), I wish webcomponents had been part of one of the initial steps of HTML.


Separating concerns is still good. The idea that we can achieve that by writing HTML and JS code in separate files is mistaken, however.

1. The concept of HTML being for layout, CSS for design, and JS for interactivity has not been true ever since web apps became a thing, if it was ever true. It’s been a decade and a half at least since JS wasn’t integral to both layout and design. So separating HTML, JS and CSS into separate files does not actually “separate concerns” because the concerns overlap.

2) Placing in different files is not the only way to separate concerns. You can still separate concerns within your .jsx file. Encapsulate your JSX generation code into a separate function, set of functions, and you can achieve similar separation of concerns, while still keeping code that are intrinsically tied together highly co-located. If you really think that separating them into different files is critical, you can put these JSX generating functions into their own file that can then be imported into your main component file.

The fact that no library/codebase actually does this, indicates to me that separating HTML into a different file provides minimal to no benefit in a component based codebase.


> What deep tradeoffs are Solid or Svelte making in exchange for their speed

I wonder why so many folks care about performance. I guess it's the only objective thing you can throw in someone's face as an argument.

But I think one of the major benefits of Svelte is a better mental model for state management. It hides the right pieces of complexity, while both React and Solid throw them in your face.


> I wonder why so many folks care about performance.

Its been shown repeatedly that application performance dramatically moves the needle on retention, eg [1].

Personally I care about it because using slow software makes me feel like I'm ill. And developing slow software makes me feel like I'm bad at my job.

Your users have spent thousands of dollars buying hardware that can run billions of operations per second. They do that in order to run your software fast. (If they didn't care about performance, they'd be using old hardware.)

Your users didn't spend thousands of dollars buying super fast hardware just to get you off the hook for doing good engineering. Slow software is a sign of sloppy craftsmanship. I hate it.

[1] https://helda.helsinki.fi/bitstream/handle/10138/273640/Mast...


I absolutely despise slow software. But what I meant to say is that performance of modern frameworks is comparable. There's a huge UX difference between 250ms and 500ms page render. Not so much between 25ms and 50ms.

When I'm looking at Svelte or Vue I care about developer experience way more than their performance compared to React.

If performance mattered as much as you're claiming, React would never gain traction. After all, Virtual DOM is pure overhead.


I agree that the performance difference between svelte and vue is negligible most of the time. It might matter more for giant websites - but it’s hard to evaluate that from the microbenchmarks people keep doing.

React’s performance has never been that great. The library is large (a cost you pay for even on tiny websites). Time-to-interactive is quite long. And I can count on one hand the number of times I’ve seen shouldComponentUpdate used in the wild. Most apps just do a full rerender whenever the state changes.

React performs well enough when websites are small, and by the time a website is big, people don’t want to change their framework. The users are asked to put up with vaguely sluggish websites. They often aren’t given a lot of choice.

I think users bounce from websites due to sloppy performance all the time. But dev teams have no idea how much it happens because it doesn’t show up on metrics.

And it’s hard to fix a big, slow react website like new reddit. As they say, you can’t fix a problem with the same thinking that created the problem.


I wonder why so many folks care about owning a fast computer. I guess it's the only objective reason to justify dropping thousands of dollars on a new computer (and ruining the planet) to do the same things they could do on their old hardware, if not for software becoming progressively less efficient.


I took a look at Svelte and I think it is useless. Having a template language i stead of the syntax sugar of jsx/tsx takes the whole thing back at least 10 years (probably more).


> React isn't as fast as Svelte

Svelte is so much more than just faster.. It's reactive to the core!, you don't need redux stores or whatsoever, no react-hooks with all it's unacceptable traps and edge cases, no CRA where a simple eject shows the mess it actually is.. I can go on and on. Sorry but IMAO React is totally deprecated, it had its time, but there are much better solutions now.

Just take a few days to dive into Svelte (or even better svelte-kit) and I doubt you'll ever want to go back to the ever mounting complexity React has become.

I've been programming professionally in React from 2014. In the first years it was great compared to Angular, but today I cannot think of any reason to start a new project in React.


> Just take a few days to dive into Svelte (or even better svelte-kit)

Svelte has now been around for, what, 4 or 5 years (according to Wikipedia)?

How bad are the breaking changes to larger apps that are built with it? When I google "svelte breaking changes", I get results such as https://svelte.dev/blog/whats-new-in-svelte-september-2022

Foundational churn that cause deep and broad downstream impact can really slow down a team. Generally, backwards and forwards compatibility is a plus in my view and a tradeoff against it is worth being intentional about.


How does Svelte solve the reactive state problem that Redux is trying to solve?


> no CRA where a simple eject shows the mess it actually is

Have you looked at the svelte compiler? It's not as small and easy to reason about as you want to think it is.


> React isn't as fast as Svelte, but Svelte gets those gains by putting another compiler in your build pipeline, a tradeoff unacceptable to many.

But everyone uses React with the JSX compiler? I mean it certainly is a strength of React that you _can_ use it as a plain old library, but it's not the common use case.


Here's my hot take. I think the author is partly justified in the premise. React when it came out was really a breath of fresh air and solved a class of problems really well. Sure it had its rough edges, but you expect those to smoothen out over time. But what has happened is exactly the opposite, where it has become more unwieldy and confounding to use. If I look back at the journey of springframework in java as an example, it had a graceful evolution, becoming more refined with each version, and springboot finally hitting the sweet spot.

I think the root of the problem with react is actually the community. The web community has not figured out how to maintain software. There is an unhealthy attraction towards new paradigms and tools and an unhealthy willingness to endure paper cuts. So many practices simply wouldn't fly in any other community. Skepticism towards new ideas and a stubbornness to resist change are very important attributes for any community. It ensures that when a change does happen it passes through a very strict filter ensuring only the best of ideas get through. Tools that are built will only be as good as the community. I believe React had a great opportunity to become something cherished, but the community had to take it to that direction.


This is a contradiction in terms:

> There is an unhealthy attraction towards new paradigms and tools and an unhealthy willingness to endure paper cuts.

Web developers (who are often maligned on this site) are both too eager to move to better tools... But also, not eager enough

> So many practices simply wouldn't fly in any other community. Skepticism towards new ideas and a stubbornness to resist change are very important attributes for any community.

Yeah, and hooks had a lot of pushback at the time. The new useEffect semantics are getting pushback. These are exactly what you are asking for.

What are you wanting us webdevs to... _do_, exactly? It seems anyone can come to Reddit or the orange site and rail against UI programmers all day. But if we sit down and explain the situation nobody is very interested to listen.


Webdevs are very much part of this community, I don't think anyone will say otherwise. I definitely am not trying to malign anyone, just sharing my observations. This is of course a very subjective matter and I don't deny I could be far off from reality, but it's a personal observation for now. The community here believes strongly in critique and I hope we appreciate critique for what it is.

On the topic, the latest kid on the block is deno. New runtime is cool, but having to rewrite userland is ludicrous. Now you have deno dotenv package, (inspired by node dotenv), oak middleware inspired by koa, semver, base64, a modern web framework... where's the end to this? Reinvent the entire node ecosystem and fragment the community?

Now I never blame the creators because they are attempting something, but if this takes off I will blame the community. People should be up with their arms shouting what a terrible idea this is, but that kind of critique is something that is missing from this community. One of the best things about the web community is their unconditional positivity, but that is also their failing. I fear people will jump on bandwagon and embrace deno with both arms, we will see a race to rewrite all the popular node packages in deno, companies will open positions for deno developers, new developers will be asking whether they should take the node course or the deno course, all until the next asteroid arrives.


> It seems anyone can come to Reddit or the orange site and rail against UI programmers all day. But if we sit down and explain the situation nobody is very interested to listen.

And when someone tries to make things better with a new take or tool they get shat on here with “hurr durr those JavaScript developers always jumping on the new framework of the week”

HN, where sneering at web devs always gets upvotes and somehow never gets old


> Skepticism towards new ideas and a stubbornness to resist change are very important attributes for any community. It ensures that when a change does happen it passes through a very strict filter ensuring only the best of ideas get through

The problem is, how do you ensure that a "very strict filter" is also a good filter? The best stuff gets caught up in those filters, because the best stuff looks like nothing the filter has seen before. Or it might indeed look too much like something the filter has seen plenty of times before and (rightfully) dismissed as unimportant. And in the end it is not so much a community embracing the best idea, but the best idea taking a sledge hammer to the community.

I like React, and I think it is improving quite nicely. But Svelte seems also an interesting thing to try out.


React isn't as thin as Preact (or whatever other small library there is), but that means that React has more functionality.

This is absolutely true but 99% of React sites don't need the extra functionality if they've already accepted stopping supporting old browsers. Everyone who uses React should be testing Preact to see if their app works. It could well be a very low effort way to knock a few tens of KB off your bundle size.


I don't see why another compiler would be unacceptable to anyone; all fromt-end frameworks have a compilation step. React needs to compile jsx files, Vue its .vue files.


The right abstractions?

React's functional components are a monument to concept over practicality, and the overall ecosystem is a hot mess.

Populating initial state should not be a difficult special case. Handling state changes should not be a choice of esoteric extras. These are just basic requirements of any reasonable application.

React got quite a bit right, and it seemed cool at the start, but at a certain point the enthusiasm for "concept" diverged from actual requirements.


I couldn't disagree more.

What all these React spinoffs seem to be doing is unlearning the lessons encoded in the React architecture and replacing them with more magic by "helpfully" applying state changes immediately instead of in a controlled fashion. But this is going to create mixtures of old and new state, which creates subtle bugs down the line.

Discussions about VDOM also seem mostly pointless because it is clear to me most people's mental model of how React renders is flat out wrong. If you are redundantly touching the DOM, that means you haven't memoized your components, or you are needlessly making copies of the same state. All of these have far bigger performance implications. In fact, even without memo(...), React renders can halt early.

Quoting from the Use.GPU/Live docs, which is a true React extension with the same semantics:

"If a component renders the exact same JSX object as before, React will not re-render that child, even if the child is not memoized.

So there is a hidden semantic in React: when you construct a JSX expression anew, you are requesting that those children be re-rendered unless memoized. But if you reuse a JSX expression from before, you are implicitly giving permission to ignore any unchanged children."

This is crucial to understand when stacking context providers.

I don't get the sense that React derivatives have been used to build e.g. desktop-class apps. They mostly seem optimized for web sites.

While it is true that React does a lot of things at run-time instead of build time, this is necessary for building truly data driven apps. JSX is really Lisp quoting in disguise. If you can't recognize this, you should probably brush up on the fundamentals.


Applying state changes in a controlled fashion is just about the last quality I'd ascribe to a non-trivial React codebase. By the time you've finished with all the ceremony of memoizing everything just right so you get acceptable performance you're left with a brittle codebase full of surprises. Making one innocuous change can break all your memoizations. Or you're just as likely to find something failing to update because it's been over memoized. Manually managing all the dependency arrays for all this is very poor DX.

React deserves credit for bringing fresh thinking into the JS framework space but there's a tremendous amount of room for improvement.


So don’t memoize unless you need to. Most of the time, you don’t. This is a fairly classic case of overeager optimization. The state changes shouldn’t* particularly depend on memoizations anyway though as memoize should be mostly for view stuff (which should* be idempotent) rather than model stuff.

* = subjective and there are a few rare exceptions


If you want acceptable performance in a reasonably complex react app you absolutely have to memoize. The fact you think this isn’t the case suggests to me you haven’t worked on a big react app.


There’s a significant difference between having to memoize and having to memoize tons of stuff.

Generally you should only need to memoize a few things, and if you find that your app becomes brittle due to the amount of memoization you’re doing you probably are not handling state in the right way. If you’re using Redux that’s a common reason for this; don’t use Redux (is my advice). And yes, I’ve worked on several large enterprise React apps at successful startups.


> If you want acceptable performance in a reasonably complex react app you absolutely have to memoize

I think what OP was suggesting is that you don't have to memoize at every level of the tree / where it doesn't make sense.


Agreed. Last year, for instance, I tried Svelte. I had a great time for a while, everything was fairly simple...but then I hit a specific scenario. I can't recall what it was, but it led to me digging as deep as I could into their docs to try and understand how Svelte was doing that whole $ thing. I nearly melted my brain trying to understand it.

That's not to say hooks are much better, but I find the overall mental model to be fairly simple to understand, and I don't often find myself bumping up against React's edges.


I believe you're referring to $ not being fired when another $ below it updates the variable the first $ subscribes to. This is an expected behavior. In Svelte the order of $ matters to prevent infinite loops.

In this example the second $ won't trigger the first $:

    let a = 1;
    let b = 1;
    
    $: if (a > 0) { b += 1 }

    $: if (b > 0) { a += 1 }
With React's useEffect one can easily falls into the trap of an infinite re-rendering:

    let a = 1;
    let b = 1;
    
    useEffect(() => {
        b += 1;
    }, [a]);
    
    useEffect(() => {
        a += 1;
    }, [b]);
Great framework are supposed to prevent this kind of loophole.


I haven't done much playing around with Svelte so don't have any business injecting myself into this subthread, but your explanation piqued my curiosity.

https://github.com/sveltejs/svelte/issues/6730

https://github.com/sveltejs/svelte/issues/6732

So basically, reactive blocks are only allowed to run once per tick; if a dependency changes after a block has run, too bad, the block won't run again. That is really shocking to me. (I won't say more due to my inexperience with Svelte...)


This is all triggering my memory, I had forgotten how it actually worked so couldn't explain the issue I was having. But it was related to this exact behavior. I found it so unintuitive and difficult to grasp that I literally abandoned the project and decided to build it from scratch in React.

It's a shame because it's an otherwise lovely framework.


I think there’s a strong argument to be made here that the actual code in this scenario is flawed.

What Svelte is doing is simply covering up the flaws in your code by short circuiting an infinite loop scenario which has been coded into your app. This will have unexpected side effects, however.

That being said, I think useEffects is far too overloaded in React, and is currently used for completely orthogonal purposes.

At he very least it’s used for the following completely unrelated purposes.

1. Component setup and graceful dismantling. 2. Syncing with external state. 3. Running code specific to a certain prop being changed.

I think the React team would be highly justified if they created a separate hook for #3 at least. Maybe a usePropsChanged hook that is called when one of the props change, and provides an isChanged function that you can pass a prop to, to check if it’s actually changed (I’m sure someone can come up with a better design than I have in the process of writing this comment).

That would be a semantic which would actually allow you to avoid the code flaw that your code above includes, as opposed to brute force papering it over like Svelte appears to do.


Novice react developers reach for useEffect way too often, because they are still thinking in terms of state transitions instead of declarative states. I have spent a lot of time teaching people not to do that. They always end up very happy once they get it, because now they can build complex UIs and have a solid strategy for compartmentalization, which makes bug whack-a-mole go away.

It's not a fault in the framework, it's a fault in their understanding, where they don't know how to implement features in O(N) lines of code instead of O(N^2).

The hint is in the name: you're supposed to think in terms of formal functional Effects that mount and unmount independently and compose orthogonally.

The result will be a code base that remains maintainable even though you've kept on adding more nuanced features over months and months.

Also, your snippet doesn't cause an infinite loop at all because modifying local variables does not trigger a rerender. If you had written setA / setB, sure, it would... but I think this perfectly illustrates the explicit vs implicit distinction.

Great frameworks don't trap developers in local maxima.


> because they are still thinking in terms of state transitions instead of declarative states

Do you have any links where I could read more about this? Or examples?


I think what you are describing looks a lot like what the Svelte team is trying to achieve with the reactive assignments "$:"

A couple years ago, that feature used to work similar as useEffect, so I got used to use it for transitions, and now is biting my ass because the Svelte team are breaking my transition use-cases


$ has a looot of gotchas, under some conditions, the reactivity climps up the dependency tree. E.g. https://github.com/sveltejs/svelte/issues/4933

I used to use "$" like useEffect, but now I don't know how to use it anymore

And Svelte still bites my intuitions when dealing with complex objects, most of the times I've manage solve it by separating the code into multiple components, but it's not clear why that happens


What happens if you do want effects to update each other's dependencies, but only conditionally? eg. A certain number of cascading updates?


Hooks are much better. The only problem with hooks is that people don't get them. But once you get them, every other approach looks like a complicated pile of shit.

I think the dev community does really poorly with these kinds of abstractions that are very simple but completely unintuitive.

I place a lot of the blame on the React team too. When hooks came out, their docs were absolutely terrible. They probably still are. They were full of shitty editorialising like "we created hooks because we found classes were too difficult for people to understand!", which made every dev I worked with feel insecure for not immediately knowing how to write super awesome clean code.


> The only problem with hooks is that people don't get them. But once you get them, every other approach looks like a complicated pile of shit.

No, some people actually get them and there are way much better alternatives[1].

1. http://intelligiblebabble.com/compose-from-first-principles/


I'm a big fan of hooks, but I'm still not completely sold on them. I like code that reads in logical sequence, like you're telling a story. When you use `useEffect` to coordinate side effects from prop changes, it makes me feel like I'm reading a story written by Quentin Tarantino.

That being said, it's a relatively small complaint.


>I'm a big fan of hooks, but I'm still not completely sold on them. I like code that reads in logical sequence, like you're telling a story. When you use `useEffect` to coordinate side effects from prop changes, it makes me feel like I'm reading a story written by Quentin Tarantino.

I actually read this as a compliment considering Tarantino himself spoke in an interview about how his non-linear storytelling style comes from the way novels he'd read were written.


That's the thing about react, there basically are no edges or very very few edges left. There were edges in like 2018, but the team has made it relatively easy to do anything you want to do, while writing scalable and maintainable code.


Agreed. I think a lot of people forgot how much pain we went through with Knockout and Angular 1 and similar magic frameworks. We seem doomed to repeat it, in some ways.


I'm learning Vue for work and getting bad flashbacks to Angular 1. Just hoping it doesn't come with some of the terrible flaws in that framework.


I can promise that it doesn’t— nothing is as bad as $digest loop hell was lol. It has its own quirks and gotchas of course, all frameworks do, but it did learn from Angular 1. That said, I’m not up to date on Vue nowadays, I was using it on its first release because we’d been hurt so bad by Angular 1 at the time.


"this is necessary for building truly data driven apps".

So where should we try to draw the line at what is truly the kind of "app" that deserves this much JavaScript, versus a "glorified website" that management wants to see lots of interactivity/animations/etc.?

In my career, I've struggled far less with choosing a JavaScript framework for front-end interactivity, and far more with justifying how much JavaScript goes into Web experiences these days, without any concern for the end-user performance impact or other impacts that may not be as obvious, e.g. accessibility.


It’s worth to note that this crucial to understand thing is only ever mentioned deep inside the API reference. If it’s this essential and never once mentioned even in the advanced section of the documentation, that’s on the project and not on the developer struggling with react. They are using it as advertised.


Here's a link to the docs for anyone else who is interested to read them: https://usegpu.live/docs/guides-memoization


For context, the author has only been working professionally as a front end developer for about three years - so has no such memory of $digest or ko.computed() or other such miserable kludges.


Can you recommend some really in depth reading about React?


Anything particular you want to know about it?

Assuming you're asking more along the lines of "how does it work internally?", these are my usual recommendations:

- My own extensive post "A (Mostly) Complete Guide to React Rendering Behavior": https://blog.isquaredsoftware.com/2020/05/blogged-answers-a-...

- Related, "When does React render your component?", which looks more at the source level checks: https://www.zhenghao.io/posts/react-rerender

- Dan Abramov's "A Complete Guide to useEffect" https://overreacted.io/a-complete-guide-to-useeffect/

- Shawn Swyx Wang's talk "Getting Closure on React Hooks" that builds a mini version of React hooks: https://www.swyx.io/hooks/

- Rodrigo Pomber's excellent "Didact: Build a Miniature React with Hooks": https://pomb.us/build-your-own-react


Is it possible to explain the big idea behind React in a single paragraph?


Write your code as components. The JS is nearby the corresponding HTML, and thus several teams can work on large web applications because it is so nicely componentized.


A great and succinct explanation, thanks.


Dan Abramov's blog is really good and this article in particular dives pretty deep into some React details.

https://overreacted.io/react-as-a-ui-runtime/


I think your comment here perhaps proves the author's point


Eh, this article is wrong right off the bat.

“React isn't great at anything except being popular.”

When the rubber hits the road, React is good. There’s a hundred thousand tiny little facets of its design that all contribute its effectiveness in getting functional (as in operationally successful) results. I’m no React fanatic. I hate the bundle sizes, the weird quirks with hooks, the footguns with performance, etc etc. But it works, and the results speak for themselves. I recently hacked for two weeks on React, Node and React Native to produce a CRUD app for Chrome and Android. It’s no FAANG app, being hosted locally for the site that needed, no localisation, ugly code, barely optimized… but it works! It has served its purpose well with minimal bugs for months, saving potentially thousands of hours of tedious labour. With React, I can prototype and get results fast. I’ve tried Vue, Angular, Vanilla, Blaze/Meteor, EmberJS, and even tried my own custom framework based on MobX. None were as good for getting results. For a bunch of little reasons, React is just… really effective.


The sentence immediately after the one you quoted was: "Don’t get me wrong: React is good". So dismissing the article on the grounds that 'React is good' doesn't get you very far.


React is good enough. And using a framework that devs are already familiar with is grossly underrated.

Sure good devs can learn any language/framework, but there is a learning curve and most write shitty code while unfamiliar with a framework.

Popularity is an important feature.


>Eh, this article is wrong right off the bat.

> “React isn't great at anything except being popular.”

So did you stop reading the rest of the article after you hit that sentence or what ?


The article is arguing that companies keeping using it and devs keep learning React because it’s popular and a “safe choice.”

I’m arguing that they keep choosing it because it’s effective and markedly more effective than the other choices currently available.


In which way is React more effective than say Svelte?


React Native


In my opinion React is "great" at a lot of anything, besides being popular. The original author makes the point that other frameworks are greater, and I don't agree with the unqualified nature of that judgement.

React is really effective. And that makes it "great" in my book.


You're basically agreeing with (and summarizing) the article, so I'm not sure what exactly you think the article is wrong about?


Any examples of places you think React's design does better than say, Vue or Svelte?


I had the unfortunate job of learning vue recently and it sucks hard at some edge cases.

Specifically, imagine you a component that takes an arbitrary node to render. Just pass the node to the temple right?

Ha.

This api sucks -> https://vuejs.org/guide/extras/render-function.html

Compared to having “{node}” in react.


They are almost literally the exact same API. Prior to the “automatic JSX transform”, they were basically identical. That’s how both libraries support JSX, which isn’t always exactly a mapping to h but is almost totally in both React and Vue (and Preact, and even in Solid if you ignore recommendations to use its custom JSX transform). The API you’re criticizing is specifically good because it enables what you prefer in React.



What do you mean by a component that takes an arbitrary node to render?

Do you mean a component that renders out to a node?

Or a component that takes in a node external to the component so it can render to that external node (as opposed to or in conjunction with a node inside the component)?

If the first, isn't this just the job of the component's <template> or jsx?

If the second, isn't this what slots are for?


Yikes. That does not look sane to me. Duplicate vnodes doesnt work, so you HAVE to use some function to generate it instead?


> Duplicate vnodes doesnt work, so you HAVE to use some function to generate it instead?

Yes. Mutable vnodes is a huge mistake that I've done long time ago when I've tried to figure out how to write efficient diffing algorithm (2014-2015), and a lot of libraries copied that terrible idea without deep understanding why I've done it in the first place.


In my opinion, two-way bindings are evil...


For simple inputs it’s fine. What are really solving by methodically doing that one-way?


Two way data bindings works in the absolutely most trivial case.

As soon as you go any amount of complexity higher in your program two way databinding is pure poison.

Two-way databinding is the absolute very worst feature people took from Flex.


> When the rubber hits the road, React is good.

Except the back button doesn't work right.


That's history management. Not a React concern.


Say that to the user.


That... doesn't make sense. The user isn't complaining that React is bad, just that your app is bad. And your app is bad because you handled history incorrectly, which has nothing to do with your choice of UI framework.


You know what else works? HTML <form>. And I guarantee you 100 percent the <form> is miles ahead of your React "app" in internationalization, accessibility, performance and portability.


I’ve built many real world web forms. React (or similar) is the only way to keep them sane.

Interdependencies between fields. Toggling visibility, dynamically changing drop downs based on previous values.

They almost always require local and remote validation. Sometimes long running validation that needs to be triggered early so it’s done by “submit time”. If it’s not done the submit needs to wait.

Any and all invalidation based on changing previous fields. Adding explainability. Submission preview. Mixing multi-media with regular text values. Complex error messaging that sometimes requires interactivity (e.g. uploading images may have errors for image quality and it’s nice to have the ability to crop or re-center an image from the error message).

If you think my requirements are over and above, maybe, but if you care about user experience it’s critical.

If you think the forms I’m building are “overly complicated” and “rare”, I disagree. Almost all of the above even apply to one of the simplest/very common usecase: “What is your address?”. eg handling global addresses with ergonomic drop downs, postal code validation, previewing the address and asking for user input for normalizing the address, etc. Similarly very common use cases for forms, contact information with phone number and/or email validation.

Using web forms is basically impossible or at best user hostile in 2022.


> user hostile

No, because as a user your React "app" fails to serve my basic needs. Web forms work. (I don't care that they're ugly or don't fit your corporate style.) I also don't care that they made your life difficult as a programmer. Sorry.

P.S. I've done my share of frontend programming too, so I feel your pain. Kind of. But sacrificing user experience for developer experience is not the way of the future.


> that they made your life difficult as a programmer. Sorry.

> But sacrificing user experience for developer experience is not the way

I think you misunderstand my last comment. It’s not “difficult to maintain ergonomic web forms”, it’s roughly impossible. I know that sounds facetious but it’s true. There are too many under-experienced developers or developers who don’t “want to learn” or respect front end development. As such what should be simple is almost always broken.

Three years ago I joined a team, their “relatively simple” (16ish fields) web form took 3+ seconds to load. I got them to add React (ie increase page weight) and lazy migrate to components over 3 months. We dropped time to interactive to 500ms (including the server latency), improvements got made in weeks rather than the previously scoped months reducing time on task for our users, developers were happier and users reported better feedback.

This isn’t the first time I’ve personally improved a “simple web form” with React, and I know of many such success stories. You can disagree with me. You can argue they were bad developers. You can argue you would never have fallen into those traps. You might be right. But my description above is very much the reality of a very many “simple web forms” and definitely true for all complex web forms. Using a framework is just the better default.

> No, because as a user your React "app" fails to serve my basic needs.

Could you elaborate? Is it the “JavaScript required” issue? Increased page weight? Something else?


Nice of you to dismiss something as essential as validation as “corporate style” while somehow pretending to be on the side of user experience.


Using the Web Platform and using React are not opposites, you can do both. See: Remix as a framework that bakes in these ideas, but using the platform is easily achievable yourself too.

Making this distinction between HTML <form>s and React shows a clear misunderstanding of the programming model that React provides. It targets the platform in a native way. This is how React DOM, React Native, and libraries like Ink[1] work.

[1] https://github.com/vadimdemedes/ink


Maybe, but I've never (as in not even once) seen a React "app" that didn't try to re-implement the web platform and didn't fail on many user-facing metrics.


"JSX is a gotcha-riddled kludge to clumsily shoehorn HTML into a JavaScript function return."

Author's opinion, and one I find very strange. JSX with TypeScript is one of the best features of React, it's a dream compared to Angular's awkward arcane syntax (that didn't have type checking until what, a year or two ago?).

I get that people don't like React, that's fine. But "React is popular because it's popular" is an intellectually dishonest argument. There are obviously good reasons technically competent people choose it for projects.


I think it's a combination of the network effect along with the "good enough" element. There is a point where a framework gains inertia regardless of whether or not there are better offerings simply because it's what people are used to. Companies like solutions where there is an substantial pool of developers from which to choose. Etc...

It might actually be popular because it's popular; that isn't necessarily a dishonest argument on it's own. But usually when something is popular because it's popular it's also technically competent to enough of a degree that it's good enough.


Or... hear me out... None of the existing alternatives really have been good enough to completely rewrite their applications for.

It's disingenuous to say that React got popular for no reason and now people just don't want to change. React-isms ooze all over everything that came after it. If it was just "meh, good enough" until something better came out, then why does Preact name itself after React and have a react-compat mode and base itself on JSX? If React was just "meh, good enough" then why does every other framework out there take inspiration from React and when React came out with something all these other frameworks came out with their implementation of that feature?


But Angular's even older than React is at this point. That said, React gained a lot of popularity while Angular was in the limbo of AngularJS to Angular 2; I think a lot of people switched up then.

I'm currently doing Angular again and I hate it (especially combined with NgRx, why do I need half a dozen observables, reducers, actions, selectors, etc just to make a HTTP request?), it's a step back from React in my last assignment; React's functional style with hooks and react-query was a great combo.

I'm not saying it's the best, but it worked for me. For my next trick, I should learn Vue.

Although on the other hand, front-end fatigue kicked in years ago. It's just the same thing again; some forms, validation, layout/style and a REST API, just using the tool-du-jour. Sigh.


Wasn’t the Angular to Angular 2 switch driven by React?

I distinctly remember when React came out, pretty much every framework out there had to pivot to incorporate at least one of the 2 major ideas React brought with it (or at least, these were the most immediately beneficial features at a time when IE was still officially supported). The virtual DOM and one way data binding.

One way data binding didn’t even exist as an option in any other web framework and it was such a breath of fresh air. In fact, competing frameworks used to strongly advertise the fact that they had 2 way binding and how awesome it was. And 2 way binding looked great in your toy TodoMVC app, but absolutely failed when developing applications for real world use.

And the virtual DOM was so much faster when it first came out.


For personal projects I'm now using HTMX & HyperScript + Django (I have a custom middleware and view class I wrote that steamlines a lot of it).

That's helped a ton with the frontend fatigue for me. All the benefits of a SPA without writing any JS.

So far I've not gotten to use that stack professionally, but I'd sure love to.


Some context: the author only has three years of professional experience

https://www.linkedin.com/in/joshcollinsworth


You discount the 4 years they spent at Flywheel 2015-2019.


That's as a support engineer, which is quite a different job.

I should have said "software engineering experience" instead of "professional experience".

I'm not impugning the author, but it does provide context as to why he may not understand React's design choices.


There's React Stockholm Syndrome: downsides of React are often praised.

Somehow people think there's a lot of foresight and wisdom in JSX invention. There's just so many good properties JSX has. But JSX was merely an easiest solution to an immediate problem.

Think about how React was created:

1. DOM management complexity gets out of hand. You solve it by treating view as a function of state (great idea btw).

2. If you do it naively, it is going to be slow. You make it performant with VirtualDOM.

3. Now that you went with VDOM, writing HTML is a nightmare. You address it with JSX.

JSX is obviously a great replacement for manually written render functions. But you know what's even better? Not writing render functions at all.

Same with setState() vs MobX/VueJS approaches. setState() was (is?) a horrible way to manage state. But it was the easiest thing that allowed you to implement V = F(S) formula at the time.

setState() a cost, not a benefit. JSX is a cost, not a benefit. I wish people stopped praising it.


JSX wasn't created whole cloth for React. It had predecessors it drew upon and there was more "foresight and wisdom" than what you are dismissing. E4X was a direct syntactic forebear. "MVU" approaches (the pattern that results in "render functions") have been quite popular in functional programming languages for a few years before React adopted it. The performance benefits of Virtual DOM were almost incidental to implementing the "MVU approach". (They helped sell it a lot, and React wouldn't have lasted if it didn't yield good performance, but the approach existed outside of just the performance benefits, including the developer experience benefits.)

JSX is easy to dismiss as a "hack to solve problems", but there was more thought put into it than is immediately obvious. It's no less a template language than other template language. It has trade-offs and advantages. At least it's not pretending to not be a template language like Angular's pretends to "just be HTML" even though it is very much not just HTML (and is closer to ColdFusion, to be unjust).


My comment was in response to "JSX with TypeScript" being a great feature of React. We may debate whether it's actually great, but this feature is accidental, there was no foresight.

Facebook was using React in 2011, TypeScript was released in 2012 (and it's not like it was immediately adopted).


Facebook was using Flow at the time and even though they couldn't have predicted the convergent evolution that produced Typescript nor the tide winds that would have pushed Typescript to prominence over Flow, they still designed JSX for static types from the beginning.

Even the predecessor tech I mentioned E4X, which were the XML extensions to ECMAScript 4, the "lost" JavaScript version, were built on static typing. The most controversial feature that killed ES4 was static type hints. ES4 never directly showed up in browser support, but it did impact web development as ActionScript inside Flash and ES4 had influence on Typescript's syntax. (In some fun ways JSX with Typescript is almost a "Revenge of ES4". It's a lot better than what ES4 would have been, but it's so heavily influenced by ES4 there's a family resemblance and clues that language design is always more evolutionary than revolutionary.)

(Not to mention that the functional programming languages like OCaml and Haskell which inspired the "MVU" patterns are all about strong static typing.)


Flow "early version" (0.1.0) was released in 2014.

Now there's a chance that they had another version used internally at least 3 years prior, but at this point we're just speculating.

But IIRC nothing in React docs at the time mentioned how great JSX is with static types. It was all about render functions.

For now I'm sticking to Occam's Razor and the idea that JSX was a hack to make render functions usable.


JSX being more easily typed is not a coincidence though.

React was not built with JSX in mind. React was built with JavaScript in mind. JSX was simply syntactic sugar. In fact, JSX was entirely optional at the beginning and all the initial React documentation had examples with and without JSX.

https://web.archive.org/web/20131118055243/http://facebook.g...

The key point is that JSX being syntactical sugar on top of a system designed to return JavaScript is what makes it work so well with Typescript and Flow. The key insight here was that components should be described using JS and not HTML. JSX was invented as syntactic sugar to make this more palatable for scores of web devs who had only used HTML. It is this decision to settle on JS vs HTML that directly led to JSX fitting in so nicely with Flow and TS since those are designed with JS in mind.


I'm just speaking from my experience of working with other templating languages.

JSX has tradeoffs, but is way better for DX and for writing stable code. I've also worked with handlebars etc, Angular (significantly) and various other back-end cludgey templating languages. Nothing is as good as JSX.

To dismiss my experiences as "Stockholm Syndrome" is mildly insulting.

I don't care about the grimy details of its origin story, I care that it helps me ship good products.


Is setState() that bad? If you want the magic of vue’s reactive state, you can just use Proxy which is what it does under the hood. Not sure why React hasn’t standardized that but /shrug


Because Proxy wasn't supported when React was designed. I bet if they were to design it a year later, they would go with Proxy. But it wasn't an option at the time, Proxy is not something you can polyfill.

Now, the community doesn't know about that. So when you tell them that there's a better way to deal with component state, they immediately get defensive: "No, setState() is way better, there's no magic, it's very explicit".

But setState() was a necessary evil, not a genius invention. They made it super-explicit because it was the only way they could do it. Not because of some great foresight.

Is it bad? Probably not. I bet it's tolerable. But why settle for less when there are better alternatives?


This is ahistorical.

Proxies have been around for at least a decade (here’s a 2010 talk about it

https://youtu.be/sClk6aB_CPk

)

React hooks have been around for less than half the time as that.

Proxies for setState would be a terrible idea in React for the simple reason that non state variables also exist in React functional components and have dramatically different behavior than state variables. Proxies would make them both look basically the same after initialization which would lead to a ton of bugs as devs lost track of which variable was a state variable and which one wasn’t.


I don't think you're arguing in good faith.

> Proxies have been around for at least a decade

Having Proxy described in ES5 standard and having it supported in browsers is two different things. IE market share at that time was around 30-40%.

> non state variables also exist in React functional components and have dramatically different behavior than state variables

Stateful functional components were introduced in 2018 (React 16). I'm talking about 2011-2013.


What is your recommendation for web apps that are not highly interactive but need interactivity to improve the UX?


All the major frameworks require you to work off a foundation that's built for high interactivity, and I believe going with one of the major ones (except Angular) is still a good bet.

Technically you can use Vue as a library to add interactivity. It works ok, but you'll switch to compilation eventually.

Still in my opinion Vue strikes good balance between getting shit done and developer experience.

Svelte would be my next bet, I just don't have enough experience with it to recommend it.


Something like Alpine JS or similar would make sense for a project like that.

https://alpinejs.dev/


HTMX & _hyperscript


I write React without JSX. That's a beautiful thing. I don't think I could forego the weird invented syntaxes of vue or whatever.


> JSX is a gotcha-riddled kludge to clumsily shoehorn HTML into a JavaScript function return. The only thing worse than using JSX with React is not using JSX with React.

Not sure I understand this, or if I do understand it, I definitely don't agree. HTML's a tree. Function calls are a tree. They're similar in nature and they map cleanly to each other.

> Or how you can’t use some standard HTML attributes in JSX (because JSX doesn’t know the difference between a React prop and an HTML attribute). Or memoization. Or how there aren’t real conditionals, so you have to rely on short-circuit operators. Or how preventing infinite loops is your responsibility—even though there aren’t really loops, so you have to use array methods…you know what, let’s just move on.

These are natural consequences of representing HTML as code, and they help me understand the first quote a bit better. I still don't think JSX is bad. Putting flow control into the template language in the style of Vue, Angular, or even the supposedly logicless Mustache ends in a programming style that I dislike, where the dividing line between template logic and logic in the actual code isn't clear, and you need to refactor heavily when you reach the gaps in what the template language lets you do.

They're closer to failures of EcmaScript. Coffeescript and Ruby weren't ideal, but their syntactic sugar would have let you do (in ES-like pseudocode):

    const TodosList = ({ todos }) => (
      <div class="todo-list">
        {
          if (todos.length > 0) {
            todos.map(t => <Todo key={t.id} todo={t} />);
          } else {
            <p>No todos yet</p>
          }
        }
      </div>
    );
Blending code and data can look a bit scary, but it lets you copy the blocks of code around like normal. You could (in a theoretical world where if statements returned the result of the last line of the branch) just copy that code outside the JSX, and have it work properly. With horrible JSX ternary operators you still have to rewrite, but that's the fault of the JS part of JSX not the underlying language-agnostic concept, and it's still something I prefer to putting logic in the template language itself.


As soon as I see the JSX critique I roll my eyes. This has been around since reacts inception and it just doesn't hold any water for me. I remember interviewing with a company in 2019 that was still on Angular 1 because they didn't like JSX, and didn't want to learn typescript. It just "looked yucky" to them.

Very very poor reasoning. I have never thought to myself, man I wish this wasn't JSX and just normal Javascript, to myself in the 6 or so years I've been using React. It just isn't something that anyone should care about and it shows the author has probably been biased against React forever, for no good reason.


I understand the instinctive reaction against JSX. I did a lot of Perl and PHP way back when, when it was super common to have bits of template sprinkled hither and thither with logic woven in here and there, and it made maintainability a nightmare. When the world moved on to dumb templates and embrace of MVC, it was a huge relief. JSX felt like a regression in that regard, but in practice, I think it ends up being pretty straightforward, in part due to the lack of any real flow control inside of it, and in part because of the convention of having small functional components which return a JSX tree, rather than bits of JSX just popping up everywhere here and there.


> JSX felt like a regression in that regard, but in practice, I think it ends up being pretty straightforward

> rather than bits of JSX just popping up everywhere here and there.

I did see lots of codebase write jsx like this. So I hate it. I starts the journey of front-end from jquery, ejs, angular.js, react to vue. And jsx of react always feels like a bad step to me.

Yes, If you write jsx properly, then it is just as readable as a normal template. But somehow some people never get it. And react also never made any attempt to stop insane codebase like this to exist.

(And you'd better pray your previous codebase owner isn't one of these, or you are in a big trouble)


You can definitely do JSX wrong. React doesn't do a whole lot to protect you from it, it's true. But, in a project which uses it well, I hate it a lot less than I once did.


> in ES-like pseudocode

In valid ES, you have many options even if none is perfect.

With the "horrible" ternary operator:

    const TodosList = ({ todos }) => (
      <div class="todo-list">
        {
          (todos.length > 0)
            ? todos.map(t => <Todo key={t.id} todo={t} />)
            : <p>No todos yet</p>   
        }
      </div>
    );
Without the ternary operator:

    const TodosList = ({ todos }) => {
      let todoContent;
      if (todos.length > 0) {
        todoContent = todos.map(t => <Todo key={t.id} todo={t} />);
      } else {
        todoContent = <p>No todos yet</p>;
      }
      return (
        <div class="todo-list">
          { todoContent }
        </div>
      );
    };
If you allow the repeat of the div:

    const TodosList = ({ todos }) => {     
      if (todos.length > 0) {
        return (
          <div class="todo-list">
            { todos.map(t => <Todo key={t.id} todo={t} />) }
          </div>
        );
      } else {
        return (
          <div class="todo-list">
            <p>No todos yet</p>
          </div>
        );
      }
    };
With a separate render function:

    const renderTodos = (todos) => {
      if (todos.length > 0) {
        return todos.map(t => <Todo key={t.id} todo={t} />);
      } else {
        return <p>No todos yet</p>;
      }
    };
    const TodosList = ({ todos }) => (
      <div class="todo-list">
        { renderTodos(todos) }
      </div>
    );


Probably should have been more clear. It's not that the ternary operator is horrible when used judiciously in a small toy example, it's that it's difficult to parse with longer blocks of code or any complicated flow control. Consider the following very contrived example:

    const Todo = (todo) => (
      <div class="todo">
        {todo.status === 'UNFOOABLE'
           ? <UnfooableError todo={todo} />
           : todo.size === 'GIGANTIC'
             ? <TextBox value={todo.body}>
             : (
                 <div>
                   <p>I've run out of creativity but just imagine this has more stuff</p>
                   <p>And that there's a good reason not to make this its own component</p>
                   <OneLineTextBox value={todo.body} />
                 </div>
               )
        }
      </div>
    );


Thanks for expanding! And do you see my other three refactorings similarly lacking?

To me it sounds as if you just didn't like JavaScript: the statement vs expression distinction constrains all non-JSX code too, e.g. you need to use the ternary operator to conditionally assign a value to a const variable.

Similarly, your example functions have long multi-line expressions as bodies so for the small gain of not needing the curly braces and a return statement, you pay a huge cost of not being able to use any statements in your code.


> Thanks for expanding! And do you see my other three refactorings similarly lacking?

No, all four are fine and most people use them in code all the time. They're not completely identical to ternary operators because they move the location of the JSX outside the place where it's used, which can make it harder to read the code at a glance.

> it sounds as if you just didn't like JavaScript

Yeah, I see that as a failure of EcmaScript, as I said in the first comment. JSX has to work within the unfortunate boundaries of the language.

> for the small gain of not needing the curly braces and a return statement, you pay a huge cost of not being able to use any statements in your code

That wasn't intended to be a meaningful part of the example, I was just writing the shortest component that let me show a particularly style which would be nice to have in EcmaScript instead of ternary operators.


Sure, that's hard to read. So don't write it like that. Early returns; decompose it further; pull the `size` out of the todo data model and into a view configuration; etc.


I don't write it like that, but I wish I had better alternatives that weren't hard to read, one of which I described in considerable detail.


Yeah, this example highlights the weakness of conditional expressions in Javascript in general. JSX is expression-based, and so you end up in this situation. DSLs added on top of HTML can add something resembling the conditional statements that many are used to. Still, JSX needs the TC39 proposals for the do expression or pattern matching to pass to improve the situation.


> HTML's a tree. Function calls are a tree. They're similar in nature and they map cleanly to each other

Yes, this is a key point. Indeed, many other 'constructed artifacts' compose nicely as trees, and thus functional languages are a natural fit for defining them parametrically.


> JSX is a gotcha-riddled kludge to clumsily shoehorn HTML into a JavaScript function return.

Oh boy, now that’s some flame-bait. I don’t like JSX, and like the Author also prefer Vue over React, but I know a lot of people simply dislike other frameworks *because* they don’t have JSX (or, as is the case with Vue, it’s theoretically possible but no one uses it).


> I know a lot of people simply dislike other frameworks because they don’t have JSX (or, as is the case with Vue, it’s theoretically possible but no one uses it).

Count me in that camp. My take is that while JSX isn't perfect, it's less of a cludge (and much more flexible because it compiles down to JS) than the templating languages that other frameworks use. I'd love it if they'd add just a little bit more sugar to JSX though. Support for JS-style comments would be top of my list.


{/* I would be so happy to never have to do this again */}


Doesn't every editor have a "comment" hotkey? I can't remember the last time I typed block comment characters in any language. cmd-/ in IntelliJ.


I don't want to make the whole line a comment. I just wanna add a comment where the language don't want me to.


Select the fragment you want to comment out, then hit cmd-/. It doesn't have to be a whole line.


Mine doesn’t work very well in JSX blocks. Partly because I don’t think there is any way to insert a comment inside a JSX tag (to comment out an attribute).


It is possible:

<Button

  // id=“commented-out”

  onClick={doSomething}
/>


Yep, I've recently used Vue instead of React and I hate the magical templating system. Slots, magical rules for variable scoping etc. The templating is IMO way worse than JSX.

I don't care for React one bit, but IMO JSX is the highlight of React. Everything else in React is pretty much just OK at best (and some not even that), and the development of React itself has been extremely slow with very relevant few features.


JSX is more than tolerable if you use React as intended.

You're not supposed to write single components that span a thousand lines of code nesting pure javascript and JSX elements.

Even better if you can factor out any computation out of the JSX parts into selectors.


+1 As someone who never runs into problems with JSX, I have definitely wondered if the criticisms against JSX/React are from people trying to use it in ways that are explicitly counter to its core philosophy.


The great part about JSX is some random new framework doesn't need a VS Code plugin to get syntax highlighting, and type checking Just Works.

I can accept a template language for a major framework where I can count on decent developer tooling, but it's a hard turn-off when evaluating niche frameworks.


Huh, that’s a pretty good point I never thought about. It’s not relevant to me personally, but having such a standard is certainly helpful.


JSX semantics are tied to React, aren't they?


Definitely not. They’ve always been explicitly implementation-agnostic (literally specified as not having any semantics). An increasingly popular JSX transform (used by Solid) has very different semantics. JSX semantics are more like an s-expression than anything else. Code as data, you can do anything with it you like. I use it to make art and render that to meta links on my personal site. You can use it to render CLIs, or even JSON responses on a server.


Not necessarily - bunch of languages have adopted JSX with slightly or substantially different component semantics from React (for example Vue, Solid, Forgo, Crank).

A Crank component (which is an async generator) feels very different from a React component. Likewise for a Forgo component, which uses closures for state and doesn't have automatic rerenders. Solid doesn't have components in the traditional sense at all.

Although the syntax they use for representing HTML is the same, the rest of the framework can have arbitrary design.


Maybe I haven't tried hard enough, but it was a pain doing JSX/Typescript with mithril. All the TSX tooling expects a React API and if you use something else you get a ton of annoying type errors.


I used TSX with Cycle.js for a while and didn't experience too much trouble. Typescript has some simple compiler options to change how it generates JSX or JS and doesn't bundle any types out of the box for TSX: all of the React API types come from React's type library. Sometimes that was more of detriment than if there were base types in TSX because reimplementing mostly the same set of standard HTML elements and HTML-like attributes a third time in a different .d.ts file when switching VirtualDOM implementations was a chore. (It was fine, but it was a chore.)

If you are seeing errors that are React specific, most likely means you just need a subtle tweak in your tsconfig.json.


This critique doesn’t hold water. In fact this entire style of critique is misleading.

Let’s apply it to Excel.

Not the best community. Python’s is more active and technical.

Not the best at collaboration. Google sheets is natively collaborative.

Not the best at charting. Tableau is superior and much more powerful.

Etc.

But it doesn’t matter. Excel is the best choice for most analytical users.


The company I work at hired a financial analyst and his first task became to standardize some reports/data according to textbook practices. He said it’s a headache to do in a spreadsheet and he’ll better use python.

Excel may be the only choice for those who grew up without accessible programming around, but times change.


> React’s performance relative to the field is pretty well-documented, so I don’t feel we need to go into it here. But suffice to say: if your goal is to build the most performant thing you can, React isn’t what you’re considering.

React is amazing in that you can build nearly anything in a mediocre way and it'll probably be fast enough. And when there are performance issues, there's a ton of resources and tools to figure out why and how to make it better.

That's not to say React has great performance. Everything in our field has performance tradeoffs. But on the whole, I think it's really disingenuous to say React's performance is bad. Python is orders of magnitude slower than Rust but for any use case where performance is that critical, you weren't fretting about language choice in the first place. If you actually had a use case where you're rendering a massive spreadsheet or lists with tens of thousands of nodes or some other wildly complicated UI, React can do the job if you really wanted it to, but why are you even fighting that battle in the first place?

Most UIs are boring. Dialog boxes. Forms. Tooltips. If your CTO is trying to optimize one of these UIs for sixty frames per second instead of thirty, they're an absolute fool and shouldn't be evaluating front end frameworks.


How did we get to a place where it's unreasonable to expect to change some text boxes within 50 million cycles?


When computers started doing a billion cycles per second, you can shift your whole mental organization to prioritize other things. You can waste a ton of the computer's time rather than waste your own debugging something the user won't even notice.


we can waste the users' time you mean?


Milliseconds at a time, sure.


"50 million cycles" is a meaningless measure far detached from the actual work being done. You're choice of front end framework has almost nothing to do with total CPU use: how the text box looks (rounded corners, drop shadow) has far more impact on cycles overall.

But it doesn't matter. Cycles are not in shortage. CPUs are mostly idle. If something takes less than 16ms to complete, you simply won't notice.


The real question is, for your application does it matter if some text boxes are rendered in less than 50M cycles or not?


Yes, for every application.


That is provably false.


Do you mean "people still use VSCode even though many interactions have unnecessarily high latency" or "people's experience using VSCode would not be improved by the elimination of these latencies?"

Can you post the proof you are referring to?

Here's some article about this topic: https://www.gigaspaces.com/blog/amazon-found-every-100ms-of-...


The former.

> Can you post the proof you are referring to?

The fact that applications which use 50M cycles to render text boxes exist and are very popular is proof in itself.

There is not a significant difference in the product if it uses 10M cycles (Or even less) vs 50M, as long as it is fast enough.


Right, everyone will use applications that are unbearably slow when there are no alternatives, and that's why we should not try to make applications that run at reasonable speeds.


You realize that the example you used is the top used tool in it's field and that field is littered with tools that have existed longer and are arguably faster?

You know why VSCode is the leader? The tradeoffs of a little latency that can be annoying but mostly is unnoticeable is acceptable for all the added benefits the editor gives us.


Good point. Also probably the performance problem will come from some slow query on the server side rather than some React code on the UI side.


Can you elaborate on the final sentence of your post?


A CTO should be worried about the big picture and product quality. Not an imperceptible performance difference. CTOs should be detached from the implementation details of the code except where it poses long term risk to the business. A text box rendering in 0.2ms versus 0.6ms is a useless distinction for a person in leadership to waste their time on.


"JSX is a gotcha-riddled kludge to clumsily shoehorn HTML into a JavaScript function return. The only thing worse than using JSX with React is not using JSX with React." - JSX is the best part of React. Without it i would not even work on it or even consider any other framework. Hence i consider Solid as the only viable better alternative.


I agree - I think JSX does what templating languages have been trying to do for years.

That being said, solid is hardly the only one out there competing that can use JSX:

- https://github.com/vuejs/babel-plugin-jsx

- https://mithril.js.org/jsx.html

- https://preactjs.com/guide/v10/getting-started#setting-up-js...

I think people are starting to see the power of it when it's used in a functional manner (rather than early class-based components). A lot of alternate template libraries are only minorly different in syntax and use different styles of interop to handle the crossover. I think .svelte and .riot are fairly close, while still being somewhat html-like, rather than JS first.


Does anyone of those have granular updates? I think granular updates makes Solid a great framework.


That's kinda moving the goalposts. I agree that Solid is one of the more viable competitors to react for the combination of JSX + a VDOM-less model (this operates much like svelte), but my point was that it wasn't *Solely* Solid's use of JSX (there are many others adopting or trying to adopt JSX) that makes it viable.


Agreed, other than JSX, React is an otherwise pretty meh UI library.


At least he admits not having JSX is worse in the very next sentence! "The only thing worse than using JSX with React is not using JSX with React."


I would like to have JSX in Angular


I think he undersells the virtue of being the “least likely to be regretted.” That is criterion number one for me if I’m trying to pick something that will be used for years into an uncertain future.


I’ve seen some incredibly regrettable React code bases (and teams that had to manage them)


I sincerely doubt that would be better with any other framework. With React, there at least are enough good examples for complex code bases.


Every company I've worked for has some sort of shit show on their codebase. Using React was never a guarantee that your code was going to be great, the tool doesn't determine the outcome. You could have the best equipment and if your builders are trash the house is still going to be mediocre


What's the point of this article? An attention getting headline followed by some bombastic claims followed by walking them back later in the next paragraph. It's like generating debate for the sake of debate.

I get the impression these things exist just to keep engagement numbers up


Same reaction. This stuff is catnip for curmudgeons.


Author has 3 years in the industry, probably at the peak of the Dunning-Kruger curve


The article starts to edge on the switching costs issue and just misses it. Dislodging a great incumbent -- even if the greatness comes from its network effects -- generally takes either the ability to eat it from the inside when marginally better... Or being well past marginally better. Most of the article is ultimately just not that important, for most use cases meriting a SPA, to give you the ecosystem benefits. React was such a tool, but the new ones are have individual innovations that are great but just not a night and day step up for teams. The market has rejected the categories in the blogpost as too weak ROI.

I do think it's fair to wonder what new frameworks ought to solve. Ex: As web GPU finally happens, we'd expect framework churn. Or, maybe it will be less about the framework, and more about the AI, or GIS+AR integration. Or some incredible tooling stack, like copilot is doing for autocomplete. Or maybe better multilplayer mode & collaboration. Just not smaller bundles and faster first paint.


> Vue is one of the most successful and well-funded open-source projects in history.

Don't be ridiculous. I will not believe such kind of hyperbole without concrete numbers. In 2021, the Linux foundation had a $177M revenue. Does Vue's funding compare in the slightest?


"... one of the ..." is a fairly weak assertion


That's a fairly weak article then.


Is revenue really the defining factor of success for "open source"? Is higher revenue the indicator of "well funded"?

I think not. Open Source success would be indicated by adoption. And "well funded" indicated by sustainability of the project.

And in thos regards, Vue is both very popular and well funded. And among open source projects of current era, it is one of the most well known one akin to linux and git.

PS: Comparing a 6yr old project with 22yr old one is hardly fair. Not to mention that linux is quite big in scope


"But it’s remained a consistent 80% of the pack for three years now, which doesn’t seem like a strong sign of continued adoption."

Bizarre take. Market share may not be increasing, but this means that 8 of 10 new projects are currently choosing React...if that's not continued adoption, I don't know what is.


I've had the opportunity to train junior developers on React, Vue, Svelte, Solid, and even Angular. And I've used Ember professionally.

The objective time-to-profficiency has made React (and Solid which is quite similar to React) the most obvious choice for us, and I'm one uncomfortable with consensus. Svelte doesn't quite have the staying power of React or Vue yet. Since it's a superset of JavaScript, it's harder to teach, and the component frameworks just aren't there yet. Vue is great, but Vue 3 took a step towards performance and a step away from intuitive readability IMO- it's probably better suited to a team with homogeneously high experience.


> (and Solid which is quite similar to React)

How is it similar when React lets you write non-incremental algorithms when you working with your state and with Solid you are forced to write incremental algorithms? Simple aggregate (GROUP BY) use cases that your average junior developer will be able to solve in 5 minutes with React will be a huge problem even for experienced Solid developers. The only similarity is that it is also using JSX syntax, but with completely different semantics.


That’s ironic because Vue 3 is soo much more React-like with the useThing() syntax.


This is surprising that folks picked up React faster than Vue/svelte/solid. I suspect that they already have prior react knowledge


I don't understand why people don't base their apps and frameworks off of standard browser and JS supported techniques like custom elements and template literals with tag functions like Lit. Is this fragmentation really still serving a purpose or just legacy support for choices like JSX that were made in the past when these standards weren't available yet?


I feel like an entire generation of programmers got cheated and didn't have to write desktop applications to get "their software" used in any real world context. As a result, they don't really understand what's possible, and the simple ways you can go about it... particularly, as you've flagged, with all the modern tools available in "standard browsers" now.

The way I see people using flexbox makes me cringe a little, too.


Can you elaborate on that flexbox comment? What don't you like about flexbox?


I love absolutely love flexbox. This is super opinionated and based on the types of software I'm typically exposed to.

I think most people just don't understand how to get the most out of it in terms of creating user interfaces, and use "table" oriented thinking like percentage widths and media size queries to control overall layout.

I think you should use it the way that something like QT's BoxLayout and GridLayout containers work. Strictly using flex-grow and min-width, max-width and justify-content to control layout. I can design just about any interface with just these CSS classes, with very occasional use of the three properties above:

    .VBox    { display: flex; flex-flow: column nowrap; }
    .HBox    { display: flex; flex-flow: row nowrap;    }
    .VGrid   { display: flex; flex-flow: column wrap; align-items: flex-start; }
    .HGrid   { display: flex; flex-flow: row wrap;    align-items: flex-start; }
    .Grow    { flex-grow: 2; }


There's a project called Sciter that uses a sub/superset of CSS and HTML to create native apps. They have their own flow styling for this, and boy is it nicer than flexbox: https://terrainformatica.com/w3/flex-layout/flex-vs-flexbox.... More details here: https://terrainformatica.com/2018/12/11/10-years-of-flexboxi...

I know the author pitched this as an idea to w3c a while back, but I don't know why it was rejected in favor of flexbox.


What I like about my style, is that the document structure enforces the layout structure. The two are much more closely bound, and with this style, you can perform arbitrary levels of subdivisions of your containers.

Working off your last link, the final "holy grail" example, with less style but the same exact layout: https://jsfiddle.net/Lpedja35/

You don't have to have a matrix with an artificial rank to represent this. I only need to specify the 1 and 4 rows once. I don't have to make a square and then decide how to divide it, which, is the "table thinking" I mentioned earlier. I just observe which elements need Grow and then design from the inside out.


> I don't understand why people don't base their apps and frameworks off of standard browser and JS supported techniques like custom elements

Because 12 years after their idea was pitched Custom Elements still suck?

Just a tiny list of problems with them, with big consequences: https://twitter.com/Rich_Harris/status/1198332398561353728

> and template literals with tag functions like Lit

The whole field of programming has taught us not to use string-based programming and not to rely on regexps for parsing said string based programming to arrive at results.

Also. Why are you against JSX and React, but at the same time happy with such "standard" things from Lit like magical reactive properties and bullshit like ".value=" and "?hidden=" and "@click=" none of which are standard browser techniques.

> for choices like JSX that were made in the past when these standards weren't available yet

What standards? Very few frameworks want to touch custom components with a ten-foot stick. Yes, most can target them, but very few have the as the underlying abstraction because they are just horrendously bad.


component: custom element wrapped in init(name, store, listOfUpdateFnPair)

view: uhtml or lit-html (don't use lit-element)

action: DOM event delegation for intercepting anything happens on view

model: a global store passed to when custom element is defined.

update: list of [selector, f({model, view}] pairs passed to when custom element is defined.

---

Congratulation we now have a self-contained Elm architecture.


I think TSX/JSX is one of the top reasons to use React. It is so tightly integrated with Typescript and the IDE/VSCode that it allows you to type check your markup at every step. That was one of the biggest things I missed in Vue (2). But I think these days Vue also supports JSX (?).

Other reasons are that you have a lot of control over what gets re-rendered when using memoization, with the huge but that there a lot of foot guns. As well as it is easy to write terribly performing code in react, while it is really hard to write fast/good code.


What the author fails to realize is that being popular (I.e. shared language and network effects) is extremely valuable.

With React you know it will work and scale (In terms of your organization) well. You cannot say the same for many other frameworks yet. For a company that has pretty generic frontend needs React is probably the best choice.


This. Vast majority of the companies out there are NOT software companies. Meaning, they don’t have full time developers, at least none with decent experience, on a full time payroll. Their internal tools/portals/sites are either maintained by contractors every now and then or junior developers/interns. In these cases, popularity of a technology, documentation, ease of hire, being able to hit the ground running etc are far important than a slightly smaller bundle size and a few extra ms response time. It’s a difference between being able to hire someone easily and not i.e being able to develop features vs months of delays and cost in order to hire a senior “efficient” dev for one of the lesser known platforms.

Choice of tech stack falls somewhere middle or bottom of the list of things to consider when delivering a solution/product. Good enough is good enough. Other factors are far more dominant after a certain point.


Yeah, you can point out ae many flaws as you want, but popularity, longevity, and inertia are the main business priorities. Before React, angular js was popular for this very reason despite its well known issues and digest cycle headaches

Technical merits are secondary concerns and only become primary when software engineers are empowered to make these decisions


I dunno, by my reckoning the following are the top items in the category.

  Performance: Solid
  Learning curve: React
  Bundle size: ?
  Scalability: React
  Community and support: React
  Financial backing: React
  Developer experience: React
  Hireability: React


Also...

"Good enough, let's spend time considering other things instead: React"

It may no longer be the best at anything anymore, but it's a polished well-rounder that will probably be fine for the typical web app. Less cognitive load when you just use it and follow the herd.


React wouldn't be my pick for scalability. For large, complex and dynamic pages, its performance is significantly degraded by the virtual DOM. There are various workarounds to limit the size and frequency of virtual DOM renders, but they can only go so far, which is why we now have concurrent mode. Solid and Svelte are more scalable in that sense.

Learning curve: Hooks can be quite unintuitive for the React beginner. React's learning curve was far gentler when all components were classes and the lifecycle was simpler.


I dunno, I’ve been with React for 4 years now, and while I’ve seen a lot of funky stuff, hooks weren’t generally the issue (though I wouldn’t say never).


Are you putting react there because you consider it to have the largest learning curve? If not, I'd probably substitute Vue.

When I was first getting into reactive frontend frameworks it was part of a time-sensitive project, and we chose Vue because we could basically just write HTML and sprinkle in the reactivity. This was back in the Vue 2 days before they made everything functional, and I still think that older Vue API is the most self-explanatory for people who already know HTML and some vanilla JS.


Bundle size is probably Svelte, if I had to guess.


What are some other frameworks that you use for comparison?


Vue, Vue2, Solid, React, Svelte (only a bit). Those are the ones I have experience with anyway.


If the premise is to be believed, the article is only making the problem worse...

Personally, I can't stand writing JavaScript and prefer to insulate myself against the moving target that is ECMAScript by writing declarative UIs in ClojureScript + Reagent, which uses React behind the scenes: https://reagent-project.github.io/

There is some interesting new stuff on the horizon like Hyperfiddle Photon, which compiles network I/O for you. As for me, an old dinosaur, I'm tired of learning new syntax. Clojure the language has not changed since its release. Lisp has been around since the 60s. It will be around in another 60 years. For me, it is the 100-year language. I'm sure it's not the end goal, but I am willing to bet it will be a Lisp-like.


This article really undersells the value of a stable, popular API.

React keeps getting picked because it has an ecosystem. And that's the most valuable thing for medium to large scale enterprise jobs. Web developers are positively thirsty for abstractions that are powerful enough to get the job done without having to learn something new in 2 years.

In an industry of near perpetual churn for the apparent sake of churn, having something you can just cling to that does the job almost all of the time is great. You can focus on the actual problems you want to solve while someone else burns their time arguing whether you could solve them faster with Vue, hypothetically, in a spherical development environment where everybody on the team was already Vue experts.


Stable? Classes vs functions & hooks is two completely unrelated APIs for the same thing, and that sort of churn is all over.


And yet because they're still under one framework they inter-operate relatively smoothly.

Far more smoothly than if one were trying to change from React to another framework. All of my old class-based components still work under my React hook-and-function code.


React is a mature project with a huuuge ecosystem of libraries and components. It is wery well tested. While not being particularly great at anything, its not worst at anything, either. I dont expect a competent dev to ever encounter performance issues with it.

Other frameworks have their own problems. Solid requires a custom babel compiler plugin. Some are new and lack components, placing a huge backlog to reimplement everything from scratch, just not worth it.

We need a framework that will not tie components and libs to itself, so they can be used with other frameworks or with plain ts as well.


> We need a framework that will not tie components and libs to itself, so they can be used with other frameworks or with plain ts as well.

That's why I wish web components would see greater adoption. Having worked through jQuery, Backbone, Sencha ExtJS, AngularJs, Angular 2 and React over the course of a 15 year career, It's frustrating when you can't switch frameworks because the cost to rewrite your existing components trumps the potential efficiencies of adopting a new set of design patterns and affordances.


> Solid requires a custom babel compiler plugin.

Don't all of them do though? Like @babel/preset-react for example


No, babel is completely optional for react+typescript.


I think the key to react's success is that it's basically just javascript and so works well with typescript.

Just write a function that returns an element.


Bingo. The great lesson that React learnt from Flex is that your Components should just be code. In Flex your fancy MXML components are 1 to 1 mappable to plain Actionscript.

Not templates, not an opaque resource bundle, not some whole other thing. Just code.


How do you write such a long article of bold claims without mentioning a better alternative? If React is so bad, what’s better? Why not put your alternative through the same analysis with the same criteria? This is yet another lazy “I don’t like React” take.


svelte is way better


Personal viewpoint alert: I deeply despise React, and have turned down job offers simply because they made that framework choice. Vue is so much more simple and concise, and its CSS markup in particular is just incredibly good. If anything, React gives you way too much rope to hang yourself and you end up with some mess like quoting CSS inside of some object to apply to another object


In my opinion CSS should not go anywhere near the component code. With bootstrap or something similar (even some dissimilar frameworks), much of the "extra styling" is achieved with utility classes. Not using utility classes and a consistent, thought-out CSS frameworks leads to great pain when scaling the codebase.

Bootstrap is a lot like React. You don't appreciate the "bloat" until you need it. Or worse, you recognize you reimplemented the wheel a dozen times without noticing and most of your "wheels" are polygons with a different number of edges.


The majority of my Vue SFC have no css/styling in them - using the utility classes of a general library (bootstrap/etc) is generally pretty good. There are times when you do need some override, or something custom local to a specific component. Scoped CSS in an SFC is very useful. I had to do some react a couple of years back and I was more than a bit surprised it wasn't supported. "Oh, you can use this plugin" but... the other 4 people on the team didn't use it, discouraged it, and saw nothing wrong at all with needing to coordinate style changes specific to one component in relatively disconnected style files. I got one "it's better this way" but I think he was meaning "this is what I already know".


In my opinion it is harder to get stuff like alignment right. The various utility classes in Bootstrap (and other framework) are a blessing because you can have things like "give me two times the usual margin to the right" without having to hardcode the margin value.

Using any specific CSS - scoped or unscoped - for a particular component is not a good sign. This might not always be avoidable.

Vue has a mechanism for that, but you can't really exchange it for something that fits your needs. It's going to be there, trying to please you with all the features the upstream developers thought you'd need and you have to program around those feature.


> Using any specific CSS - scoped or unscoped - for a particular component is not a good sign. This might not always be avoidable.

I don't generally disagree. Component-level CSS is something I don't do all that often, but when I do, in Vue, I'm glad I can keep it in the same file (generally scoped). For me, it's easier to spot the edge cases (oh, this is modified, and here's where it's being done).

Even at the component level, you can see use system-wide offsets. "give me two times the usual margin to the right" may be a general rule, but for componentX, something needs to be three timex the usual margin, so... you can still reference a system-defined margin variable, but have that 3x override where it's needed.

Again, not something I do often but, imo, the Vue SFC style scoping makes it easier/safer to do when needed.


React may or may not be the best choice today but one thing to remember is that every single UI framework today (Vue, Angular and even beyond Web: Flutter, SwiftUI) borrowed React's component model and I am glad they did. It's such a beautiful abstraction and so much more manageable than anything we had before it.


Interesting observation given that Angular, Dojo, even BackboneJS came out before React, all going for a component-based UI framework.


Angular 1 was a mess of filters, controllers, scopes, directives, services and what not. The only closest thing to what we call a component today in their was directive but it was never the main abstraction

BackboneJS was MVC iirc? Don't remember if they had any notion of self contained component but it was very different from the MVVM paradigm react introduced.

No experience with Dojo so can't comment but I remember MVC being the paradigm with most mindshare before React became popular.


Other ongoing thread:

Introducing Svelte, and Comparing Svelte with React and Vue (2021) - https://news.ycombinator.com/item?id=32763509 - Sept 2022 (187 comments)


Choosing react, because others choose react is simply another word for "quasi standard" or "industry standard".

For me, who hires Devs and works with react daily, having an industry standard is wonderful. I still remember the stressful and heated days of the past. Where every 6 month a new framework came out.

Today, I can hire a junior developer and within 24h they contribute to the code. No need to train them for many months. This makes both lifes much nicer. I don't have to spend a lot of time training. And they feel like they are contributer early on.


Don't know anything about your company or product, but I've been in 4 different companies where React was used. Every single one had different setup, best practices, state management lib, "the way" of doing things, bundler (create-react-app, next.js), etc.

Each project was so big, that I'm little in doubt about your statement "within 24h they contribute to the code". It could be your react apps are very very small or junior devs are very very good and probably shouldn't be called juniors.


I spent a few months learning HTML, CSS and JS because I thought they were the backbone of web development. I got decent at it and found it pretty enjoyable, because everything seems to make sense - HTML structures the page, CSS handles the design, and JS handles the functionality. React, on the other hand, I find very confusing. I don't understand what problem all that complexity and abstraction is supposed to solve. Aren't HTML/CSS/JS really good and time-tested tools for web development on their own?


React solves problems you don't often run into when making simple websites with simple functionality.

Once you start trying to build complex, dynamic web applications that involve loads of state changing over time, and user and API interactions, it can get really messy and cumbersome. Think Gmail, Spotify, Facebook.

Now if you try to add other engineers to the project, without some sort of framework, it's difficult for them to understand what's going on, or to change things without cascading consequences.


The one thing that drives me crazy with react compared to angular (having moved to a react shop from an angular shop) is the fact that every react app we have in house is architected/structured differently. One is using nextjs and xstate, another is using react router and redux, another is a CRA based app, and so on. At a large org you wind up needing a committee to try to standardize on app architecture. With Angular at least, most things have well defined patterns.


I used to think like this, but nowadays I think that's no a real problem, at eñadt to me. I find it very easy to go across different JavaScript projects with different libraries, etc. Usually the worst part is understanding the business domain, the warts of the application, the know bugs, problems, etc.

The libraries used, as long as they have documentation and are supported and more or less widely used...that's fine, they're easy to learn. And if I have to switch between 10 different projects, then for me that's the actual problem, not the fact they have different architectures.

What has been a terrible experience for me, was when at two past companies in an attempt to "standardize" they ended up with custom in house libraries and wrappers, all of them built in house, undocumented, with the original developers already gone and nobody knowing/wanting to touch them. And then the rejection of any kind of improvement or modernization because "then that new app will have a different architecture"... So what? We have a terrible one, and we need to do every project terrible, so everything is consistently terrible.


Its an observation a lot of React evangelist ignore.


The fact that React is “good,” in the author’s own admission, combined with its raw popularity and staying power is why I would still choose it for any greenfield project.


I thought the title was a reference to what every developer I know said about React after a few months of working on React when it first became popular:

"React is amazing but it won't live forever. It's hard to imagine what the framework that takes its throne will look like but it will probably look nothing like what we've seen before. Either way, React can't be the end. There will be a next framework."

So far that hasn't manifested. Vue arguably took some learnings from React but it feels more like a step back than a paradigm shift in some ways (not that that makes it bad, mind you). Remember that React took its throne from Angular and remember how Angular looked at the time. That's the kind of change we're looking for.

Most React developers I know know that React will go away eventually and that they'll switch to something else at that point. Mind you, they all didn't start out as React developers, so this isn't their first rodeo. But that new "genre defining" framework (as the article puts it) just doesn't exist yet, or if it does, it hasn't gained any real traction.


This article, and all the ones like it, remind me of Worse is Better. Specifically, the key point from that essay is:

"The lesson to be learned from this is that it is often undesirable to go for the right thing first. It is better to get half of the right thing available so that it spreads like a virus. Once people are hooked on it, take the time to improve it to 90% of the right thing."

This post concedes that point in the first couple of paragraphs. Much like C and Unix-like systems, this is why React isn't going anywhere. Indeed not based on the competition it has now. The best its competitors can do is convince React to steal their ideas and keep pushing toward doing 90% of the right thing.

[1] https://www.dreamsongs.com/RiseOfWorseIsBetter.html


JSX is awesome. And it is optional. React picked js-first approach. Everything inside curly braces is a valid js expression. So you can use more and more vanilla js features and be happy, while some angular-first frameworks forces you to use some strange semantics; They also make you learn new pseudo attributes - ng-if, ng-for, etc. Those are not valid html attributes. And you cant translate that knowledge anywhere else.

With react you just need to remember to pass className instead of class and sometimes to pass key prop and you are good to go. Overhead is minimal. Since jsx is optional, you can write <Component value={1} />, {Component({ value: 1 })} or createElement(Component, { value: 1 }), which gives you so much control.


Not sure I understand the point of this article. It seems that we're trying to talk about how popularity doesn't reflect the most advanced technical solution. But where is that the case? Java's adoption is huge compared to say Clojure or Elixir. One reason why people choose React is due to being able to hire a specific set of developers and leverage the huge eco-system of tools, libraries and information surrounding React. React has reached the late majority now, and it's everywhere. Most of these mentioned libraries, i.e. Svelte or SolidJS, are probably more in the early adopter phase. These things take time.


One criterion the article omitted was portability: I haven't followed React Native for a few years but I imagine a lot of people want a framework that will allow them to share code between mobile apps and web apps.


React popularized component based architectures for frontends by making them incredibly easy to use in a time where people constantly fought against Angular idiosyncrasies.

It was a breath of fresh air.


When some CMS only adopt React or Next.js as their tier 1 JavaScript framework this self-fulfilling prophecy keeps renewing itself.


Interesting to see that Angular only comes up in Scalability & Financial Backing sections.

And I do agree that in every other metric Angular is worse.

However, I feel that developer productivity wise and team output wise, Angular is a safe and reliable choice.

I only wish there was some framework that has the tenets of React and the structure of Angular.


Angular is moving in the right direction now I think.


Probably there will be a grass roots if devs hacking at home with not-Reacts, loving it, bringing it to work.

It is not like you need to only use one framework per company. There is a lot of melting-pot coding happening out there.

React was probably successful in part because it didn’t require a rewrite.


Depending on the scale and goals, there are huge advantages to companies standardizing on one framework.

Nothing burns more than having to dedicate an additional quarter to a project because half the code you need to finish the task is sitting atop another API or, much worse, in a different language.

And when we're talking web apps, There's real material cost to the end user in using more frameworks than are strictly necessary. React is large, but it tends to be large with a spanning set of features that means you don't have to glom something else in alongside it.


I agree that it is advantageous for companies to standardize but often they don't. React + Vue in one app might be a bit crazy but React in the main app and Vue in an internal app, or some secondary app might be OK. Resume-driven development is a thing, as well as joy-driven development. Devs are gonna be devs! There is a mild conflict between what is good for a devs career and what will make the shareholders of that company the most money. It is almost like a super-polite tug of war over future potential dollars between the two. Mostly incentives align but sometimes not.


Vite works with React. And you can get the same performance as Vue. I get thé author’s general point. But most of us are not trying to innovate on front end frameworks. And a CTOs job is to make a better product. Not a playground for their experiments.


It's popular to hate on React. I still like it, and much of the "dislikes" I hear come from not actually understanding React and using it in the "functional programming" way it was designed to be used in. Same with Redux.


The author mentions:

>Besides JSX, React itself has its own bevy of unique conventions and trip-ups (not to mention two completely different syntaxes that are not fully interoperable).

But elaborates no further. Does anyone know which two syntax they are referring to?


React is:

- Good enough

- Easy to find developers for

- Extremely well supported with libraries for whatever you want to do

- Good enough.

I'm convinced it'll still be the top framework ten years from now. That better frameworks exist is just not relevant, the above are what matters.


I have been in 4 different companies, with a decent to very good salary. React is self-fulfilling prophecy also because developers want to make as much money as possible and companies need more React developers because, at least in my experience, development is so much harder and slower with react - so companies need more react developers, and because there aren't many in the market, price (salary) per developer goes even higher.

So everybody learns React, because companies need more React developers, because development is too slow. Think about it, which developer would prefer framework/library that gets job done quicker and easier, but pays less?


Your reasoning may be backward: Companies with poor codebases have middling developers, and middling developers choose the most common languages.

It's the same with Java versus Clojure. Are LISP macros really the reason those Clojure devs seem so productive compared to Java bodyshops? Or is it the most talented devs going after exotic technology, and the less able going for the lowest common denominator?


There is no problem with react, it’s an amazing piece of technology that has moved us all forward.

There is a problem with people over using and abusing it.

And it’s not react’s fault.


Feels like every time someone criticizes React, they assume the people using it are clueless idiots that mindlessly follow the crowd.


People who assume that suffer from the Dunning Kruger effect


Tired: React

Wired: Web Components


Have Web Components solved any of these issues that don't exist in any of the "tired" frameworks https://twitter.com/Rich_Harris/status/1198332398561353728 ?


That tweet is 3 years old. Web Components weren't ready for prime time a few years ago. Google has the Lit framework is using it in Angular. Web Components are here to stay. I'd like to know what Rich Harris thinks about Web Components today. Microsoft just released their Web Component frame work:

The adaptive interface system for modern web experiences. Interfaces built with FAST adapt to your design system and can be used with any modern UI Framework by leveraging industry standard Web Components. Standards-based Web Components are the foundation of each FAST component, making them compatible with almost any modern web framework, including those listed below.

https://www.fast.design/


> That tweet is 3 years old. Web Components weren't ready for prime time a few years ago.

So. Have they solved any of the issues listed?

> Google has the Lit framework is using it in Angular.

You've missed a few words in there.

yes, Google has Lit. And yes, Angular can be twisted to use them (but doesn't use them by default).

> Web Components are here to stay. I'd like to know what Rich Harris thinks about Web Components today.

Literally nothing you wrote answers my question.

And the answer is: no, despite the tweet being 3 years old and web components "not being ready for prime time then", none of those issues have been solved in the three years since.

---

Edit. As to what Rich Harris thinks about them now?

https://twitter.com/Rich_Harris/status/1518912939876618242

They're the past. Specifically, they took our best ideas circa 2010 and ossified them into the platform

https://twitter.com/Rich_Harris/status/1513638143584518154

I don't see any evidence of [fameworks will be transpilers to native web components in the next 5 years]. if anything, i think we'll see frameworks begin to explore the notion that 'component' is a purely author-time concept

etc.


Not only is Rich Harris is a fast talker, he expresses more strong opinions per minute than most, except perhaps Richard Feldman about Elm. I like Harris' passion. He believes his way is the best. More power to him, but I'm not going to argue with you after coming across this quote recently:

Too much gaslighting from a parent as a child turns you into an argumentative person desperate to prove your version of event's because you're used to being dismissed in an unfair power structure (tinybuddha.com)

I will say I've been building Web Components lately and think they are elegant and beautiful and solve some problems in a neat way, but of course don't solve all problems.

Also this: Angular elements are Angular components packaged as custom elements (also called Web Components), a web standard for defining new HTML elements in a framework-agnostic way. https://angular.io/guide/elements


It's funny how you keep ignoring the original question and trying to talk your way out of it.

So. Have web components solved any of the problems listed? Yes. Or no. No buddha quotes.


What I hear you saying is you want me to do research for you. Ok, I'll bite, I'm retired with nothing better to do.

The Guide to Accessible Web Components

https://www.erikkroes.nl/blog/accessibility/the-guide-to-acc...

Server Side Render Web Components: It's a common myth that you can't server side render Web Components.

https://dev.to/steveblue/server-side-rendering-web-component...

Using SVGs in Lightning Web Components

https://developer.salesforce.com/blogs/2020/07/using-svgs-in...

There are various work around for global namespace problems

You're welcome


> What I hear you saying is you want me to do research for you.

What you hear is me asking a direct question and expecting a direct answer. All I hear in response is non-answers.

> to do research for you.

I wish it were research and not a couple of links you just grabbed from a quick Google search.

> The Guide to Accessible Web Components

Translation: the problem is not solved because Shadow DOM isn't accessible. Relevant quotes:

"""

Building proper UI Web Components can be quite a task though, especially if you want them to be accessible.

As the shadow DOM is completely encapsulated and isolated, it is also completely disconnected. It's almost like it's a completely different document like an iframe.

When one of both (the label or the input) is in the shadow DOM, they're in a completely different context. This makes it impossible to refer to eachother. This same dillema also goes for WAI-ARIA attributes like aria-labelledby, aria-describedby and other that reference an ID. You need either both elements in the shadow DOM, or both of them in the light DOM.

"""

I'll let you do the research further. The only "solution" on the horizon is manually adding more boilerplate Javascript to your components when Acessibility Object Model becomes available in the browser.

> Server Side Render Web Components: It's a common myth that you can't server side render Web Components.

It's not a myth. It's pure reality. Which you'd know about if you bothered to read the links you provide.

The link even states this clearly: you can't render them. You have to use a very specific set of third-party tools that jump through hoops to provide the DOM object on the server. This is not a generic solution provided by the platform, you have to buy in to specific frameworks for this to work.

> Using SVGs in Lightning Web Components

And here we see that you didn't even understand the question. No one said you couldn't render SVG from custom components. However, you cannot do this:

   <svg>
     <x-axis min="2000" max="2019"/>
     <y-axis min="0" max="100"/>
     <scatter-plot points="..."/>
   </svg>
because custom elements are HTML by definition (they extend HTMLElement). Totally incompatible with SVG.

You'd know that if you had done actual research, and not spent your time attacking Rich Harris, or gushing how Google invests oney in some framework.


For the record, I didn't attack Rich Harris. I admire him. I said he was a fast talker with strong opinions and then "I like Harris' passion. He believes his way is the best. More power to him."

It sounds to me like you went down the Web Components path and became very disillusioned. That's good to know. Maybe my enthusiasm is misplaced. My goal is to keep things simple. That's why I refuse to use React, Redux, Node, Gulp, Babel, blah, blah, build pipeline. I'm not building a Facebook clone. That's not simple. We have different goals then. That's fine. Thanks for the info.


> It sounds to me like you went down the Web Components path and became very disillusioned.

It sounds to me that all you can offer is demagoguery

> My goal is to keep things simple. That's why I refuse to use React, Redux, Node, Gulp, Babel, blah, blah, build pipeline.

Does it have anything to do with the question I asked? No.


> Does it have anything to do with the question I asked? No.

This thread is on a post about React. I'm not even sure what you want from me at this point. To prove that Web Components are better than React because I said React is tired and Web Components are wired? The "The self-fulfilling prophecy of React" article says React is tired.

> It sounds to me that all you can offer is demagoguery

I'm not trying to persuade anyone of anything. I'm saying I like Web Components. I haven't built a start up around them. I'm sure they fall short in many use cases.


> This thread is on a post about React.

This particular thread started when I replied to your claim about Web Components. I posited a simple question: have the problems listed at the link been solved?

You spent an inordinate mount of time and words to avoid giving an answer. Hint: the anser is "no".

> I'm not even sure what you want from me at this point.

At this point? Nothing. About three replies ago I was still expected a clear honest answer.


So what framework(s) is better in every category, and why is it better?


Is the tide on React finally turning?


The tide will only turn when a competitor arises who has a clear advantage over React. I've all of the major JS frameworks, and while they're all nice, none of them are a no-brainer as far as ditching React.


Doesn't seem like it. It's still the top rated framework according to State of JS.

Also, what would be a better alternative, since you don't like it? Seems like it's yet another technology HN loves to hate, but every developer I know likes it.


It's not that I don't like it; I use it daily at work. It's just that I am seeing far too many people instinctively reaching for it when they need to build a frontend of any complexity, for any purpose. I was like that once myself, and I'm looking back to those days with embarrassment.

Personally, I like the movement back towards the web platform, browser standards, and web components. For many cases, these are more than enough.


We can hope, but it'll take more time for people to understand what a mediocre library React is.


Quite frankly I haven’t seen interesting enough UIs the last few years to care too much about framework advancement. Sometimes my instincts kick in and alert me that ‘such and such component rerenders too much’, but then I realize it’s some dumb text and no one cares. I move on.

If you got a different type of UI, I can see why React would not saturate your use case.


Author is at the peak of the Dunning-Kruger curve


Ansible is absurdly terrible. But good luck finding anyone who wants to use any other configuration management tool for less than 20 servers.

Jenkins is horrible. But it's by far the most ubiquitous ci/cd thing.

Terraform is less horrible, but still pretty bad. Yet it's impossible to work for any company that wants to do IaC and not use it.

If the Peter Principle says "incompetence rises to the top", the Poettering Principle should be "the most popular garbage rises to the top".


React is the Unix of the web, huh.


Liking and defending React is borderline Stockholm Syndrome at this point.


Imagine being a professional in an engineering field and thinking this situation is acceptable. Except of course being a building contractor who reduce cost by lowering grade of materials. Hopefully your new house has reasonable price.


Great article.

I see React as today's PHP... same terrible community, similar issues and also extremely messy code, yet if you dabble with it, you'll find a job where people just don't know any better.


I think the comparison with PHP is somewhat merited in that they're both practical technology communities with a "get stuff done" attitude. React is also often the entrypoint to programming these days (most bootcamps teach React) in a way that PHP used to be. I see this much more positively than you though. There's a lot of good code written in PHP these days. And it's great that programming is accessible to more people.


React is far better designed, though. Far fewer kludges. I like PHP, but it's not the same.

I think React is more like Kubernetes. Not the simplest way to do things, but standardised, various gotchas designed out, lots of ecosystem, and plenty of people who know how to use it.


> I see React as today's PHP...

I see it as today's jQuery.


That's another good one. I feel like the crowd that used to code all that horror for Wordpress, Magento, Joomla, and other PHP CMSes, slowly moved to jQuery from backend coding, and then has transitioned to React full-time as things became more frontend-heavy. Still same freelancers from 3rd world countries and junior devs who just want to pay their bills and honestly don't even like computers that much. That's why there's so much terrible software today, not just websites. Back in the 90s and early 00s our industry was full of people who truly loved computers and wanted to make something good. Today you have to really be careful what tech stack you pick, that can make a difference between being surrounded by people who just blindly follow popular trends and real badasses who can make something great out of nothing.


Yeah, React doesn't have the massive security holes baked deeply into the design that PHP did.


I don’t come from a JS background, and JS makes me very angry every time I use it. But it’s unavoidable if you want to build something on the web. I tried to pick up React a few years ago for a project, saw the JSX, and put it right back down. At the time, Vue’s emphasis on HTML templates was comforting and approachable, since I like HTML and its simplicity and visual structure. So I tried Vue, and found it was easy to go from toy examples to real, working projects with no major gotchas.

I recently spent some time learning Vue 3, and I’m a little less enamored. The composition API is nice for not requiring deeply nested code inside a giant object literal. But having my code littered with .value is ugly and a source of endless bugs. (You also don’t always need .value, such as when referencing a Pinia store. Ugh.) I looked into the pending “Reactivity Transform”, but it too introduces weird surprises and seems like its issues may be unsolvable.

Bottom line: I hope and pray for the day WASM allows Python to get a decent footing in the browser environment.


Python is the last thing you want in the browser. The sooner everyone's love affair with Python ends the better.


Python has its flaws (package management and the GIL come to mind). But the language itself is just beautiful, and _designed_. It makes it so many common tasks expressible in compact, readable code. I’d be willing to jump through some hoops to use it on the front and back.


What do you dislike about JSX? It's just a tree of function calls.


Just the visual appearance. It’s so chaotic. I’m sure it’s very powerful, and that’s why people like it. I just don’t have a very high tolerance for clutter.


It looks almost exactly like HTML though? The only difference is wrapping curly brackets around expressions. I admit that if you embed long expressions directly in the JSX it can chaotic, but I tend to assign these expressions to variables first, then put the variable in the JSX. Or break it up into another component.


I don’t think it does when the markup you’re generating gets more complex. At least, not compared to Vue templates.

What I like about Vue is that you can work up a static design, then cut and paste chunks into single file components, add in a few :attr=“someVar” bindings, some handlebars, and you’re done with the template part. You can also copy and paste and rearrange the markup very easily. It’s a nice workflow and it makes it easy to see and manipulate the structure of the markup without having to think about the JS too much.

I imagine if you enjoy writing JS, then it makes sense to make everything a function and do it all in JS.


> I’m sure it’s very powerful

JSX is only appealing to a webdev community. Modern native react-like UI libraries are perfectly fine without XML-like syntaxes: Flutter[1], Jetpack Compose[2], SwiftUI[3].

1. https://flutter.dev/

2. https://developer.android.com/jetpack/compose

3. https://developer.apple.com/xcode/swiftui/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: