Hacker News new | past | comments | ask | show | jobs | submit login
Is React Having an Angular.js Moment? (marmelab.com)
114 points by Ins43b on June 6, 2023 | hide | past | favorite | 90 comments



I was ready to dismiss the article because the answer to the title question is an obvious “No”, as server components is not a breaking change. It’s optional. But the author addresses it and then makes a very good point.

> ”The introduction of React Server Components, unlike the Angular.js to Angular 2 transition, is not a breaking change. Existing single-page applications will still work with the latest version of React. Existing Next.js apps built with the Pages router will also work. So, the answer to the question "Is React having an Angular.js moment?" is "No".”

> ”So to the question "Is React harming its community by being too ambitious", I think the answer is "Yes"”

The article is very good and well worth the read. I am inclined to agree that this is a NextJS move, that goes against the interests of React developers, with the goal of locking React developers in their own services. The React team is on board with this and playing along. I think they shouldn’t.


I think the React team is responding to current trends. SPAs were super trendy. Once people started building them, they recognized that SPAs are much harder to optimize than the code for a single page. Next.js came in, and everyone has slowly been shifting to SSR.

If the react team doesn't react, other frameworks will eclipse them.

While I don't like the implementation details, I can see what they were going for. Encapsulating certain API calls behind the server adds a new layer of security that react didn't have before. It's good it is opt-in


I've never seen the use-case.

If you're building trivial brochure pages that need SSR for adsense, you shouldnt be using react at all.

If you're building complex apps, it doesn't really make much sense to put the burden of rendering on your server.


That's the gap server components fill. With SSR you always had the option to just use React on the server and send HTML back, no JS or hydration needed. But if you then want a single widget on the page you can go back to the old (not saying bad) days where you include some clientside js that attaches event handlers and changes some HTML. Or you mark that one component with "use client" and you're done and can seamlessly to your declarative rendering on the client and use the same components you already have.

The RSC part is mostly the streaming of the JSX result, but this only solves the issue that the market wants to work in a MPA way with the routing benefits of a SPA.

Again, nothing new, Turbolinks existed and replaced sections of your HTML with XHR, but you had to slice it up yourself and manage interactions again if the section you changed required JS. RSC takes away the latter part and you're only required to define the boundaries. That's the reason why RSC has it's place, you're able to mix and match it within the same codebase instead of maintaining one codebase for your marketing pages and one codebase for your application (and one for your docs)


A lot of companies depend on search indexing from google and other platforms. E-Commerce, blogs, and trivial information websites all need their traffic to come from somewhere.

If you were going to dynamically render the page anyways, why not do it in node with the best UI framework out there right now?

The burden isn't that much when you put a caching CDN in front of it.


The things you've described do not require react.


What's a good template engine that isn't string based? Jsx and Jade are the only 2 I know. I guess you can use jsx without React if you want.


Ejs.


Ejs is very much string-based.


Svelte already has that and much simpler and more performant than react does.

If they won't do it, they'll fall behind.

With Svelte I can render a reactive statically rendered website. Nothing to my knowledge can do that in the JS framework world.


In my experience, Svelte made me much less productive because I was fighting with magic. I'd get stuck on obscure issues for hours.


I needed to learn something to build an app, and react was complex, so I tried Svelte.

With no experience, both seem like fighting with magic. I get stuck on obscure issues for hours.

I would have thought this whole process would be significantly more straight forward at this point.


This is a good point. Svelte has a lot of 'magic' under the hood but a lot of it does not look like magic which can lead to confusion.

The docs are pretty complete and well structured. There are of course obscure issues, but most of the footguns folks run into for typical use cases (e.g. doing something like using an array method and expecting reactivity) are well documented, and solutions on avoiding them are easy to find.

This means that if you do run into something which is not completely intuitive in Svelte, it's normally because there's not an intuitive way of doing it, which means you do more 'ad-hoc' learning as you try to work out what you need to do to get things working the way you want, and sometimes it's easy to fall into the trap of thinking that something that should work is not working.

React does less to 'hide' its magic and makes you work harder mentally up-front to understand what it's doing in terms of component lifecycle etc. In exchange, because it doesn't look as intuitive, you're a bit less surprised when it doesn't work.

For example, in Svelte, you might create something like:

  <script>
    const colours = ['red', 'white'];
  </script>

  Colours of the British Flag

  <ul>
    {#each colours as colour}
      <li>{colour}</li>
    {/each}
  </ul>
  <button on:click={() => colours.push('blue')}>Add blue!</button> 
If you click the button here, nothing happens, because you only mutated the array, which doesn't trigger reactivity. If you're not aware of this, you might not immediately understand that you've made a mistake.

A similar React component would look something like:

  function () {
    const [colours, setColours] = useState(['red', 'white']);

    return (
      <div>
        Colours of the British Flag

        <ul>
          {colours.map(colour => (<li>{colour}</li>))} 
        </ul>

        <button onClick={() => colours.push('blue')}>Add blue!</button>
      </div>
    )
  };
You'll get an IDE warning that 'setColours' is unused, and anyway, you already wrote the code to destructure the 'setColours' function out of 'useState', so you theoretically should know that you need to use it, the mistake is 'clearer'.


> render a reactive statically rendered website

Regular old react without server components has been able to do this long before Svelte existed with SSR


> render a reactive statically rendered website

Regular old react without server components has been able to do this long before Svelte existed. Next.js has done it since day 1. Server components solve for something else


Agree heavily with the article. As an app developer, I actively spend my time walking away from frameworks/languages/libraries that start mashing the server weirdly into client code. Each to their own but I think quasi-RPC implementations are a relic of the past.

Treating the network layer as an explicit abstraction to components just feels a better developer experience in the long run. The data abstractions are easier to reason about, and caching albeit always hard, is a lot easier to think about.

I don't even know _why_ React/Next is pushing Server Components. (Part of me wants to join the conspiratorial bandwagon like the author)


I don't get it either.

Doesn't a backend API and frontend web/mobile clients just make so much sense?


I've given server components with Next.js an honest try in my personal projects, and honestly, the pain of using them far outweighs the benefits.

I MUCH prefer the pattern of getServerSideProps seeding data on-page-load and working with it via context providers. The fact that data loaded in with server components cannot support reactivity of any kind means you have to litter your code with "use client" wrappers that take in their parent data as initial state, then introducing client reactivity on top.

That^ also means that any time you drop into "use client" you drop any SSR benefits anyway. I agree with a lot of this article that the transition feels forced, and I can't help but hope that Vercel commits to supporting pages style routing indefinitely.

Here's an example, the pattern makes it almost impossible to highlight a currently active route in a navbar. Literally a basic building block of web applications: https://github.com/vercel/next.js/issues/43704


Oh man as a non fe person this is so overwhelming. I just got the hang of page based routing in nextjs and I still feel like I am walking on eggshells. Frankly all I want is TO render a next/jsx page into a jinja style template that I can render with backend of choice (golang) while leaving some ajax loading on the page when needed. I don't need my entire application to be a single page (don't get me started on understanding routing). May be that's why I can't appreciate consumer apps.


You could use Go with templates and htmx, no js needed :-)


You know I wish I heard about htmx before I started next. Now I feel like another ecosystem to get started on :(


It's hardly an ecosystem, think of it more as a turbocharger for your backend. Your customers won't care if you chose one or the other anyway.


IL still have to "migrate" my existing apps no - sure I could use htmx for. Ew projects but I have so many inflight which is where I was wary of the change. Is there an easier way?


Fwiw I've been using react on the frontend and php on the backend for like 8 years now. It's a multi page app. It's fast. No issues. If you want to swap php for go it'd be just as easy.


Interesting. How do "break down" react to be multipage. With next atleast the folder based layout (and the [id] naming convention) I found helpful. Disclaimer I'm still a react noob.


In webpack, if you use a simple dynamic `import()`, it will compile all the files that it might possibly match. Then in PHP I just pass down the name of the script I want to load plus a bit of server-side data and render it. You can fiddle with the webpack settings about how aggressively it will code split or re-use libs. I recommend throwing all the vendor/3rd party party stuff/rarely changing libs into a single package and set a long TTL. Then the first time a user visits it can download all that junk and from then on they only have to re-download the bits that you change. For me, I might change a few pages a week. For my day job, we deploy once a day, M-Th, so even then if a user visits 100 pages in a day, they only pay for the JS on the first click of the day, and only the parts that have changed for the most part.


Client component still get SSR benefits. They just happen to be included in your JS bundle. This makes sense in the context of your example – you do expect the active route link to change during a client-side navigation.


That's kind of a really "meh" thing if you develop web applications and not websites. The static parts aren't that large, and the app kinda useless until the dynamic parts are there. So that doesn't really justify additional effort.


What additional effort?


From the article (italics mine) -

> So why is Next.js so pushy about it? (React server components)

> I can't avoid feeling that the new direction taken by Next.js is not designed to help developers, but to help Vercel sell React. You can't really sell a service around SPAs: once compiled, a SPA is a single JS file that can be hosted for free anywhere. But a server-side rendered app needs a server to run. And a server is a product that can be sold. Perhaps I'm a conspiracy theorist, but I don't see another reason to break the React ecosystem like this.


If I understand correctly, this server side component technology is strictly JavaScript (or maybe Typescript etc.), so how can it be marketed as a step forward compared to having the React pages interact with any kind of back end through reasonably standard web services?

Throwing away perfectly good backends and replacing them with new and relatively unproven JavaScript implies so much code churn, and novel deployment and management difficulties, that fatally bad downsides like the likelihood of crucifying the masochist hipster's application or site to specific cloud services seems a minor detail.

Is it simply a perversion that has been designed to appeal to exclusively JavaScript project of exclusively JavaScript programmers who have some hope of salvaging and porting already JavaScript business logic?


I don't understand your argument at all. Why would a TS backend be inferior to a PHP backend, for example?

Because for many people, that's the tradeoff.

Think of a new project.

You'll still have "OOP" PHP + some random templating language + the infamously hard to do "sprinkles" of JS.

In the end lots of people start to shoehorn their PHP or Django CMS into REST API parts anyway, reinventing the wheel over and over again, for every new requirement.

I have nothing against PHP or Django or other server technologies with corresponding templating languages.

But to churn on the "old and proven" point in 2023 seems odd to me.

It's tradeoffs all the way down.


A TS backend is inferior to a PHP backend merely due to available frameworks being night and day in favor of PHP.


A TS backend is going to have a SPA frontend, reducing the complexity of the backend significantly.

Use Koa and a database client and you're good.


PHP isn't "complex", it's nearly identical with minor variations.


My point is that the need for a backend "framework" decreases significantly if you take that burden on the frontend.

And anyone writing a JS/TS backend is likely doing that. So I would expect fewer "frameworks."


What kind of operations do you imagine an application is used for?


> how can it be marketed as a step forward compared to having the React pages interact with any kind of back end through reasonably standard web services?

With RSP you can implement a server function and (relatively) directly call it on the server, type-safely. Try doing that another back-end (I have and mostly failed).


Sounds like a potential foot-gun for input validation by the backend getting missed. :(


Isn't that the purpose of tRPC?


I’ve had this thought for a while. Companies like Vercel have coined the term “composable” but it really does feel like this is what is actually driving things.


Pretty much every app I've ever needed required an API, which meant a server, which meant Next.js would have been a viable candidate. Sure, there are use-cases that you truly don't need an API or you can just hook up to an existing one, but I don't think they're nearly as common.


I don't think any of what you're saying really makes much sense.

Merely having a server doesn't mean SSR provides business-relevant benefits.


Next.js provides API routes / initial serverside loaders for your routes. Disable SSR, Next.js still benefits from being able to write CRUD code in the same codebase and most applications need that anyways


If you think that way, you are not objectively weighing the benefits of server side rendering. It _is_ useful and shouldn't be tossed away for the benefits of a 6MB javascript blob.


You can do better than a 6MB blob. You can code split and cache. It's not that bad. Especially if it's an app, not an SEO site.


A 6MB blob is identical to 2MB, 1MB and 3MB blobs.


Not quite.

1. They can potentially be downloaded and parsed in parallel

2. They can be invalidated independently, meaning on your next visit you may only need to re-DL the 1MB blob instead of the whole thing

3. Not every page will need all 3 blobs, you might only need the 2MB blob to load the homepage which means it'll load a little bit quicker. Then you can either load the next blob on the next click, or start downloading it in the background so the next click is nearly instant

4. You can do this not just between pages, but progressively within a single page. Render part of the UI, wait for the 2nd blob, then render the components that need that bit.


I would argue it is quite similar to an Angular.js moment, even if it's not a breaking change.

> React suggests mixing server-side and client-side rendering, using what feels like black magic. You can use client components in server components, and vice versa.

This is reminiscent of hybrid Angular apps[1], which allows you to use both Angular.js and modern Angular components together and was introduced to help the upgrade from Angular.js to modern Angular. The only issue is the "black magic" there isn't as good as advertised and you'll run into many holes if working on a moderately complex hybrid Angular app.

I can only hope that the "black magic" for a mixed React app is more complete, though lack of documentation for the wire format that the author pointed out does not inspire confidence.

Interestingly enough, there is a picture of a tree of mix of components[2] on the Angular upgrade guide which parallels the one in tfa. It is basically why I think these scenarios mirror each other: an introduction to a new paradigm which can be used with the old one in a mixed/hybrid application (and a possible lack of documentation which will make that application terrible to maintain without fully transitioning to the new or old paradigm).

[1] https://angular.io/guide/upgrade#how-ngupgrade-works

[2] https://angular.io/generated/images/guide/upgrade/dom.png


I tend to agree with the article. I've felt pretty frustrated with the direction of react in the last few years. Most of the companies I've worked for that used react did so because they wanted a SPA, in most cases making a conscious decision to move away from older SSR technologies towards the SPA.

It's doubly frustrating because we primarily use C# and Asp.Net Core for back end work. A react SPA is trivial to use with any back end of your choosing... this SSR push they're making isn't much fun unless you use a JS back end (no thanks).


Many have switched to a backend for frontend design (BFF). So you have another backend that proxies and/or uses the real backend and makes SSR and other frontend things.

A better explanation: https://blog.bitsrc.io/bff-pattern-backend-for-frontend-an-i...


I totally get that it's possible, but it's completely unnecessary complexity for both deployed apps and local dev. If the react team tells us that we have to jump through these extra hoops to use react*, my response will probably be to move to a different front end framework. And I say this as someone who honestly really likes react and who never really cared for front end work prior to learning react.

* I'm aware that server components aren't required, and probably won't be in the near future. But the way they're being pushed ATM they're likely to become the de facto standard, similar to how functional components and hooks have completely displaced class components even though the latter is still officially supported.


Horrid dev experience.


What's wrong with a JS back end? Node/Express is awesome.


Node is fine (and improving), but Express, or any of the many other libraries with similar APIs, is full of footguns:

- The base request-response cycle is ridiculously dynamic: the void-returning-callback API + stateful response object makes debugging a nightmare.

- Then there’s middlewares: they can come from anywhere, do anything anywhere in the call stack. They create complex webs of implicit coupling you can’t see, can’t find with static analysis, and can’t know if they’re changed or removed.

- You can add static types to address some of the above, but you cannot have any real confidence that the types reflect the actual presence or behavior of anything. It’s all just type assertions out of thin air.

- It’s routers all the way down; if you so much as nest one on a subpath, you have footguns squared.

- Maybe more specific to Express than the overall design, an absurd set of the request/response property names are very wrong, and get wronger in common setups.

It’s possible to address all of these without leaving Node (and I have!), but you’ll end up with a radically different API. It’ll be a better API, but it’ll also create friction for the unfamiliar, at least up front.


Any experiences with Hapi or Deno re: footguns above?


No direct experience, but the fact that route handlers return responses is a good sign. Both look like they have some of the request-mutation type of footguns.


For example, it's wrong if my back end is Java. Or Python. Or .Net. Or an exotic high performance database that serves JSON. Or anything that already works and I have no reason to replace or hobble with a new JS middleman at great cost.


Express was awesome. Now it's fastify or GTFO.

Seriously, express in 2023 smh.


It's too fragmented.

Express is actually pretty cool for basic microservices.

For anything complex, hell no.


nodejs and bilions of js libraries that you will install and never check.


This move seems like something that pleases nobody. There's a crowd that hates SPAs and a crowd that hates heavy react frameworks, and there's very little else. It seems like the number one critique of React is how bloated it has gotten and how much it reinvents the wheel.

Personally, I've always like React as a library for small interactive parts of your website. It's fairly trivial to make your site mostly static and use something like Asp.Net to handle how its rendered.


Having experienced Vercel enterprise sales, I can confirm they are indeed the Death Star and will inadvertently destroy React.

Very happily using Phoenix LiveView these days.


Curious to know more about their sales...

I am already veering away from everything Vercel, didn't know RSC are so NextJS affiliated, this will certainly influence my library choices.


> React Server components require new generation routers, new generation bundlers. They are officially in alpha, and not ready for production. So why is Next.js so pushy about it? I can't avoid feeling that the new direction taken by Next.js is not designed to help developers, but to help Vercel sell React. You can't really sell a service around SPAs: once compiled, a SPA is a single JS file that can be hosted for free anywhere. But a server-side rendered app needs a server to run. And a server is a product that can be sold. Perhaps I'm a conspiracy theorist, but I don't see another reason to break the React ecosystem like this.

I mean, yeah, I see your point.

React should always be self-hostable, full-stop.


I think we as an industry underestimate the value of stability.

It's easy to always look at what isn't perfect and think, "Hey, we know better now, let's fix that", but what does more damage, architecture that isn't perfect or constant change?

It's hard to really get any momentum going when all the tooling changes every few years.


> I can't avoid feeling that the new direction taken by Next.js is not designed to help developers, but to help Vercel sell React. You can't really sell a service around SPAs: once compiled, a SPA is a single JS file that can be hosted for free anywhere. But a server-side rendered app needs a server to run. And a server is a product that can be sold. Perhaps I'm a conspiracy theorist, but I don't see another reason to break the React ecosystem like this.

Feels like this inevitably ends in a fork. It was a hell of a run though!


Vercel has raised an enormous amount of money and they are stuck with making bizarre choices like this or selling other tech brazenly for higher prices. That is why pg recommends not raising a huge round.


I don't get this argument. Who says the server needs to be Vercel. You can just npm run start on any hosting provider.


I think this is entirely a documentation and marketing issue at this point. React Server components are very new, probably new enough that most people should not use them unless they're very comfortable working on the bleeding edge.

The problem is that React points towards Nextjs as a default, and Nextjs makes Server Components the new default.

It doesn't actually change anything for anyone that still wants to develop a standard SPA. And these changes also don't seem to make any of the old methods obsolete, they simply add another method that you can use to develop web apps.


React Server Components remind me of inline PHP with html. Wasn't a good idea then. Not a good idea now.


They literally make this comparison in the next docs somewhere



Having? Had. React <16.8 (Class Components) and React >=16.8 (Hooks) are "React.js" and "React 2."


React has already through massive changes with emphasizing classes -> function components -> hooks.

OTOH it hasn't broken backwards compatibility.

I think Server Components are similar to the introduction of hooks because while they require changes to use, they don't affect anything if you aren't using them.

You could argue that it's such a massive change they should make it as a separate framework, but React's approach of adding new approaches but maintaining compatibility seems to have been fairly popular.

Maybe server side rendering isn't what everyone wants to do, but you don't have to. I think we can all agree that if they were FORCING everyone to change what they're doing and use server components it would be more of a problem?


I think, right now, they are nudging everyone to change. And if there is no pushback, like this article, in an year or two they will be forcing.


They never made such a forced (big) breaking change. I don't have a reason to think they would in a year or two.


There's another aspect to server components and server-side rendering in general: it makes sites less amenable to third-party front ends. The rise of client-side rendered "apps"/SPAs/etc. and the accompanying APIs made it much easier to develop third-party front ends since the data became available in easily-parsed JSON or XML. Server-side rendered sites need to be scraped, a process which is far less robust than API access. Given that many site owners are quite adverse to third-party front ends - just look at the Reddit kerfuffle for an example - this limitation may well be one of the intended features.


The author just doesn't get it.

> You can't really sell a service around SPAs: once compiled, a SPA is a single JS file that can be hosted for free anywhere. But a server-side rendered app needs a server to run

I hate to break it to the author, but if you're going to limit yourself to apps that don't need a server, you're going to limit yourself to only building toys. The real world is messy because you can't pre-compile all your data into your single JS file ahead of time. Real-world apps need data stored in some kind of database, and some kind of server sitting in front of that database to validate access and present it in a format that can be used by the frontend.

Now, you can build that out in a different language, in a different repository, by a different team, behind a formal, stable API. At a certain scale, that's even preferable. But when you're building new products, when you're trying to find product-market fit, the truth is, API design is just another distraction that doesn't help you build value and just delays you from getting to market. What React Server Components does is allow developers to avoid API design. Sure, that doesn't scale, but in the beginning, you should be doing things that don't scale. Leaving aside the point that, if we're being honest, most developers don't know good API design anyway.

And no, just because Vercel is taking React in a server-first direction, doesn't mean everyone is being forced into using Vercel for hosting. You can self-host NextJS anywhere you can run Node or Docker: https://nextjs.org/docs/app/building-your-application/deploy... . Which you're probably hosting anyway, because again, in the real world, you need to put something between your frontend and your database. That thing just doesn't necessarily need to be an API.


since 2014 I was using angular.js. Since feb 2016 I've started to use Angular 2, which were a release-candidate version back then and became a stable release just in oct-nov 2016! So I don't know what the author means by "Just two years later (after 2012), the Angular team launched Angular 2" but it definitely doesn't smell good!!


It's a good thing. React team needs to keep up and keep fighting on the performance story.

Longer story: I hate ALL-in-one framework/libraries.

I prefer separation of bundling, compiling, rendering,... . It's called the SRP principle.


Tldr, React is overcomplicating things like Angular did


While Angular is simplifying things now


React is a component library, Angular is a framework.

We don’t really compare them apples to apples at work because they serve two different use cases.


This is a heavily outdated opinion. The "default" react experience nowadays is Next.js and that is definitely a framework not a library.


React is a component library.

Angular.js is a framework.

Next.js is also a framework.

Comparing apples to apples, then you should compare Angular.js to Next.js, and not React.


Isn't next.js a server side framework? How can you compare server side framework with frontend framework? It's the same (silly) way you'd compare PHP with HTML!


React is a component library.

Next.js is a framework.

Angular is both a component library AND a framework.


Agreed, although NextJS is still a lot lighter to me than angular


The author is talking about Angular.js, which the legacy version 1.x, and not the modern Angular 2+.




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

Search: