1. 57
    Get in Zoomer, We're Saving React practices rant web acko.net
  1. 29

    I remember work being done offline, and I remember good desktop software. The word “offline” was rarely spoken, because it could be assumed. I can project myself back there, and I start to agree with this article, in a cosmic sense, in a “the way the world should be” sense. However, most of my experience involves harsh resource tradeoffs in brownfield projects with small teams. Most of these have been SaaS. SaaS-with-forms, even! The idea of taking a year off to build (or find) the GPU-Accelerated Reactive Tool To End Them All, so as to deliver a truly desktop-class version of these forms, would be incredibly fun. It would also be catastrophic.

    So this article might not be written for me, and perhaps I should move on?

    However, I might have something constructive to add: I might know why the author is seeing people complain about React in the first place. I do not know which specific complaints they are seeing, but I suspect many come from people who are indeed building SaaS-with-forms. Like the author, they treat that as a pejorative, and seek to deny this reality. So they use React and convince themselves they are building an “app”. Then the trouble begins.

    This article did not deliver on saving react, and that’s fine. It ends by making excuses for React vis-a-vis the deficiencies of its alternatives when building “web apps”. I do not disagree with that conclusion. However, it is responding to complaints from people whom (I suspect) are in denial about needing React in the first place. I know because I walked that path.

    My day-to-day project is old enough to have started as static HTML, added prototype (the library), switched to JQuery, added on Angular (chosen over Ember), dropped Angular for React. We have now dropped React [0] and replaced it with… mostly nothing? We eschew JavaScript [1], and just “sprinkle on some JQuery” like the old days, for the handful of isolated interactions that matter within a page [2].

    I am confident that this does not produce the Platonic Ideal of UX for our product. We are also not on a path towards desktop-class software that the author opines for.

    Yet leaning in to things such as old school form submissions and page reloads has freed up engineering time to focus on the more meaningful deficiencies of our product. Although we are little more than “SaaS-with-forms” we were not even doing that very well! This time last year we had five different sets of styles used in various places for forms, input validation and error feedback. Now we are down to three, and most of users only ever experience one (as there are hard-separated categories of users). All of the URL routing and faster render times in the world couldn’t fix the deficiencies of the actual designs of our main, existing interactions.

    Getting the confidence to say “This is not a web app, this is a web site, and it needs be a good one!” has paid off massively. If we hadn’t, I might still be grinding my fingers raw myself against component lifecycles and context and all of that jazz. I suspect there is a decent population of people who need to realize that, instead of blaming React for their woes.

    [0] With a different product, and a different team, the choice might have been otherwise. We do still have two user-facing interactions that run on Angular, and a few internal pages using React. The React pages do not even use JSX, just good ol’ React.createElement. All are on track to be sunset by the end of this year.

    [1] Except for the marketing-mandated tracking JavaScripts, of course.

    [2] I hear the cool kids use Alpine these days, but JQuery was already in the code base, so we went with that. We are slowly working towards JQuery 3, and I am impressed by the team’s documentation and tooling that exists to help people upgrade.

    1. 7

      this article might not be written for me, and perhaps I should move on?

      I feel the same. The author seems to envision something that is “reactive react” and provides a lot of interesting background.

      people who need to spend more time doing that

      But I’m just sitting here and want to do some “forms and a little interactive views” - by only consuming one JSON “rest” API. And for that, react is overly complex and things like Vue are so very much easier to get things done. Although I’ve got experience in using JQuery across a multitude of forms, I wouldn’t recommend it.

      But yes, if someone finishes a reactive-react which can do undo + redo + multiuser + live diting + gpu acceleration, feel free, I’d use it. But I would first have to find a use case. And then worry about the amount of compute I’d need for multiuser + validation + websockets, in comparison to just throwing some JSON requests over the fence.

      Meanwhile I’ll be taking more dancing lessons.

      1. 4

        I will admit Vue was the temptation that we almost turned to.
        Having done a small project with it, Vue feels like what I felt Angular promised, but did not deliver on. Vue’s official support for TypeScript is nice as well.

        I did not want to make my post longer than it needed to be already was, so I think I come off overstating how much we lean on JQuery. We also use a handful of libraries for interesting things that are best not done in JQuery, and best not reinvented ourselves: Handlebars, PristineJS, and DataTables. Sometimes there’s just DataTables instance on the page, and no JQuery code at all.

        Also, JQuery code in 2022 looks looks a little different. Not much, but some, and in a good way. I had forgotten how much of JQuery was just patching up the state of JavaScript in the early 2010’s, and even the state of CSS (e.g. animations). So there’s a lot that we don’t use because it is no longer needed. We might have even gone “vanilla”, but again, JQuery was already there, and the team knew its pros and cons well enough.

        Looking back over the last year, the main difference I have felt between using a “framework” and returning to JQuery, is that frameworks do binding of elements and handlers into JS for you. Thus there is some schlep in the setup of a page, but none of our interactions are so complicated as to be overburdened by this boilerplate.
        If we had a workflow that was deeply interactive at its core, undos and drag and drops and 50 new elements created and flying about? If we had that, then we might be creating a web app, and we would finally reach for something like Vue, or whatever the latest, lightest view-only framework is.

        1. 3

          handful of libraries
          just patching up the state of JavaScript

          I still utilize tools like select2, tablesorter and daterangepicker, they just get the job done, while being very easy to integrate. I’d probably feel bad using them for something new without bootstrap, but it still was probably the best decision. (And I’m probably just pressured into using non-jquery for new projects.)

    2. 13

      React’s a red herring here. You could also copy what Cocoa does in JavaScript and call it a day. The key point is this:

      I’m going to be cheeky and say if there’s anyone who should take the blame for this, it’s back-end engineers and the technology choices they continue to make.

      I’ve spent the last few years doing back end work, and, yes, this is infuriating. Compare the experience of writing something in Cocoa with Core Data to schlepping behavior from SQL to an HTTP API to the browser. There’s no intrinsic reason for it. There’s no reason I could not have something like Core Data, and generate the whole back end and front end client for it, and use it in my event handlers.

      I think there’s another side to this, though: most back end and front end engineers today have never spent any significant time writing desktop GUI apps. They don’t know how. It was never taught.

      1. 12

        There is a bit of a push-pull on how backend should expose it’s capabilities. Some think, it should do basically everything and just present an interface for performing all the required actions. Others think, that it should just be an interface for a database. And a whole spectrum in between. Where to land on it, probably depends on the application and team’s competencies.

        But the reason for it is that there is a barrier. Operating state is divided between frontend and backend. And you need to create a divide so that each part wouldn’t need to worry about details only pertaining to presentation or backend operation. But the problem is, a lot of the state is necessary for both presentation and operation. And that’s where the divide becomes painful.

        When doing native/offline apps, the divide is gone. You no longer need to divide your state. You just need to decide, what needs to be stored for later, and what’s fine to loose. But accessing the stored state is usually almost as easy as accessing your program state. This is extremely different from online applications, since every state request has latency quickly becomes noticeable for the user, and as such, you now have to think about what data should you access, and how often should you access it, and how much of it should be processed by the backend.

        Interestingly, similar divide happens between the backend and the database. Not as much with state (though backend is effectively responsible for session state management), but with computation. Some think that as much of computation as possible should be done on the database. Others think that databases should just be dumb key-value stores. And a whole spectrum in between. Where to land on it, probably depends on the application and team’s competencies.

        There is a barrier of where computation is quick and easy to do. Database has all of the state right there, with little latency, but it is a horrible programming environment to work in. Backend needs to fetch all of it’s data, but it has a programming environment that is easier and more flexible to work with. Once again, latency kicks in, you have to think about what data do you need in the backend, how often do you need it in the backend, and how much per-processed by the database. For example, if you get a list of users, it’s probably more ergonomic from the backend to access all of their posts individually, but it is a lot more efficient to have your database get them for you at the time you’re getting the users. You only need to pay the latency penalty once in the latter case, when you pay it for each user in the former.

        For the divide between backend and database, you could solve it by having tools that allow you to merge the database and the backend into a coherent framework. But I don’t know if you could solve the frontend and backend divide that way. The divide there exists for a reason, and it’s often a pretty good one.

        1. 1

          I’m aware of everything you say, and I think that you are still confusing what we find conventional with what is intrinsic. The idea of that code needs to run in different places but is still part of the same program is hardly new. There’s a whole mathematical structure for describing it (the ambient calculus). I should still be able to write a program and be able to state that certain parts run on the client or on the server without having to explicitly introduce HTTP routes or handle that plumbing. The plumbing is always the same.

          1. 3

            I don’t think that the plumbing is the problem. There’s a bunch of ways to at least generate the plumbing for the frontend, and some exist up for the backend too. The problem is the divide. Even if you managed to have a single codebase across frontend and backend, you still have to manage the divide of what’s running where. Having syntactically transparent function calls between the divide does not make the divide transparent. It’s still there, with it’s ugly latency cost. You could forgo the divide, and do everything on one side or the other, but both have their limitations. Offline apps are great in that they don’t have the divide, and have no limitations.

        2. 3

          Maybe this is why I’ve always felt every single backend web library/framework just wasn’t very good: they’re all so low in abstractive power while requiring so much to learn to use them.

          I always thought it was just me.

          1. 1

            When you say “low in abstractive power”, are you referring to a mental cost of HTTP transactions, and/or shuffling data in-and-out of a store via SQL? Or is there some other example you have in mind?

            1. 2

              Generally just the HTTP handler part. Newer libraries are better at deserializing things to a strongly typed structure and warning appropriately, but the work of marshaling from JSON/forms to domain object to then marshaling it to DB really grated on me. So much incidental complexity for updating a row in a database. And nobody seemed to care despite telling the computer what the schema should be at least 2 or 3 times.

        3. 20

          Wait, is this the “red site”?

          1. 6

            I’d assume so, yes.

            1. 6

              I would venture to guess it refers to reddit :)

                1. 1

                  Either this site, reddit, or perhaps YouTube?

                  1. 1

                    Can’t we be the red site someday?

                  2. 7

                    This was super solid. I gotta be “that guy” though. The last few paragraphs were really unnecessary :/

                    There is something to say for the masses to gravitate or continue to use things. We need to question what’s the overlying themes of people hating on React lately, and how it could be fixed (if it all). We need to continue also why these other frameworks exist: was it because they hated the DevX of React or they needed something more specific for their problems?

                    1. 13

                      If we’re already talking about the last paragraph, I’ll bite: Contrary to the introduction it is ranting, pretty bad one too.

                      They’re attacking “Zoomers”, which are people born between 1997-2012, so the oldest person is 25, too young to have influenced react by much. Then they basically blame them for using emojis, something the “boomers” invented (show me all the <=25 year olds in the unicode committee). (There are enough jokes floating around the internet about how “boomers” misuse emojis on facebook, to the point they’re basically overflowing their messages with them.) Wrapped up with a story that, together with this paragraph, reads at worst as follows: “I’m old and wiser, btw I did get an engineering degree, UX was better on macos, windows is shit, no need for confirmation of input, react can’t handle my requirements for enterprise-software, now GTFO”.

                      Which is sad, I really liked some of the backstory and ideas of what “reactive” could mean, and what a better “Web-app” experience could be. Even though it might be overkill for most of the things written with react.

                      ~one of these “old zoomers”

                      1. 1

                        As a millenial I got the same vibe. This post didn’t make me angry, just disappointed.

                        I was legitimately actually angry about the pointless 3d effect on the site. Like.. Why? I guess I’m not experienced enough developer to know that.

                        (Well i’m not a webdev in first place but hey)

                      2. 3

                        Yeah I agree that the author made a lot of really good points, sounded reasonable and good faith, until the bit at the end about young people not being able to dance or do math. WTF??

                      3. 5

                        Mac OS X circa 2008 was really cool, and you can go back and watch NeXT demos from the 90s that were cool too. But the system, like everything ever, had a limit that when you hit it made progress hard. You could build a Delicious Monster 1.0 app in a few months by leveraging all the cool defaults. But DM 2.0 took years because the price of overriding all that good default behavior was so high.

                        Anyhow, I just make webpages instead of web apps, so paving the cow paths sounds good to me!

                        1. 3

                          That’s a really fair criticism of Cocoa in that era. Another way of looking at it, though, is that it’s an alternate universe where your dark-matter, LoB developers were writing things that were a lot better to use than the things we actually got. I think that’s actually the main reason I’m sorry OpenStep’s Windows support couldn’t get carried forward and finished at Apple.

                          Those LoB tools never needed to get to be a DM 2.0 app. If they’d ever gotten to DM 1.0-like behavior, computers would suck less for many everyday users.

                          1. 1

                            Yeah. It is much easier to get superior UX with much less code out of something like VB6.

                        2. 4

                          I love how opening that site made my CPU scream.

                          1. 5

                            To be fair, the title kind of hinted that it would.

                            1. 2

                              Hah, true.

                          2. 3

                            Using incremental-dom to do “immediate mode” rendering where you call it every frame works pretty well IMO. Allows you to write animations with regular per-frame update. eg. https://imgur.com/a/Ilqp9AX

                            1. 2

                              That was an entertaining read. I don’t see myself switching from react because another framework has a marginally better api. I’d be interesting if there could ever be a way to implement the react api on top of no-vdom compiler like svelte’s.

                              1. 2

                                That’s mostly what SolidJS aims to do, albeit with a slightly different (and better, imo) API that nonetheless feels very at home for react devs.

                                1. 2

                                  I just looked at SolidJS. Actually never heard of it. The only advantage of implementing a compiler for react, if that even makes sense, is that you could keep the huge react community and package ecosystem.

                              2. 1

                                <norm> You know, I’m something of a developer myself </norm>

                                Personally, I think React has been going in the wrong direction ever since hooks. It’s obvious that the React team is trying to do two things: write everything in OCaml instead of JS, without ever actually committing to a compilation step; and solve facebook-specific problems, suited for facebook’s architecture. Neither of which are good for (most) react users.

                                I can assure you that there are a lot of “real programmers” who realise that components should be specified in “something like templates” because that’s the only way to stop themselves and other “real programmers” from making terrible user-experiences because they’ve gotten lazy and mixed in and bunch of business-logic crap that takes wall-clock-time into component rendering code which needs to be done in 16ms slices. It’s not done for speed, or better tooling, those are just gravy. Not only that, but pretending that react is the way it is “because developers want native expressiveness” is nonsense on its face. From day one react has gone out of its way to stop you sending messages to child and sibling components, and contorting events and messages into a reactive stream built to respond to changing values makes everything difficult- nobody has managed to solve that nicely yet. And hooks introduce a whole bunch of rules that aren’t part of JS, and also stop you from writing simple readable JS code lest you violate those rules. Good luck diagnosing exactly what went wrong when you inevitably do break them though, because everything is done with runtime magic, which no longer knows about your sources or where your mistakes might be.

                                The reactive, binding-driven model is excellent for building individual forms and components, but breaks down quickly when you’re doing things like tying the application’s data model hierarchy to the visual component hierarchy. And when we’re forced to do ridiculous things like portals to implement stupidly basic UI like popup menus or dialogs, this is a sure sign that we’re standing under the bonnet of a car holding nothing but a hammer, trying to find a nail.

                                React was a big step forward at the time, but it’s not a paradigm to solve all programming problems, and even in places where it is the best tool for the job, you simply can’t have nice readable and maintainable code that relies on a reactive model underneath if there isn’t actually a reactive model underneath. It needs to be part of your language, otherwise you end up where we are now: manually maintaining your data dependency graph with a bunch of strings which aren’t checked at compile time, and maintaining this extra burden forever. Alternatively, something like mobx can do the dependency graph maintenance at runtime (mostly), at the cost of none of your objects actually being what you think they are, and an incredibly leaky abstraction that repeatedly bites you at interface points within your application.

                                1. 1

                                  I think this article would have been better if it was framed as “Why React (and derivative frameworks) really are the end of history of Web Application frameworks”

                                  I think that’s one of the main points of the article, that if you really are making an app, there’s no reason to switch frameworks again. I’m getting a lot of “rifle is fine” vibes from this. React is a powerful tool that is “good enough” for 95% of usecases, especially once we get through the initial frustration and confusion, begin to understand why the bad react codebases are bad, and write our first well-structured React app.

                                  The author spends a lot of time focusing on “the other 5%” of use cases, the ones where vanilla React straight from zuck’s lair might stumble. It makes sense, because it seems to be what he specializes in. But for an article ostensibly about React, I think it’s a bit distracting.

                                  I will say, I have written a lot of front-end apps from vanilla JS to jQuery to Angular 1 to React. I never really wrote apps the same way after I used React. In fact, I would often end up re-creating small elements of it in my vanilla JS creations. IMO there really is something special about the pattern that React established, and the author hits the nail on the head there. Whether it’s React 16 or React 18 or Preact or whatever else, I see the “pure-ish functions which return DOM elements or models of DOM elements” as ideal in a lot of ways and I think they will stand the test of time.

                                  1. -1

                                    Unrelated, but I was distracted by the animation at the top of the page (~ 1 to 2 seconds after the page load), if you scroll up, there is this 3D pipe maze with a play button. If you click on the play button it then turns into a first-person 3D roller-coaster on the pipe maze, while playing “Selah Sue - This World” in the background.

                                    The artist and the song is displayed for a few seconds at the beginning of the animation. But I’m just wondering how this works copyright-wise…

                                    I couldn’t find the country/state of the author of the website, but the server is hosted in California. I don’t think fair-use applies here, but I’m not a lawyer. How does this work? Does the author know Selah Sue personally and asked for permission? how is this legal? It’s a genuine curiosity-driven question, I’m not trying to be nit-picky.

                                    1. 1