DEV Community

Cover image for Why Do I Need RSC(react server components) if I Already Have Remix
JS for ZenStack

Posted on

Why Do I Need RSC(react server components) if I Already Have Remix

Since its introduction in 2020, React Server Components (RSC) has sparked heated discussions in the frontend world. Next.js 13 made RSC the default option last year, reigniting the interest in this technology.

However, based on what I have heard, adoption for production usage has not been as widespread as anticipated. At a recent meet-up, some people expressed their opinion that RSC is an unconventional solution that introduces more challenges than it resolves. Instead, they believe that Remix has already successfully addressed those issues.

As a developer who has experienced the simplicity of Remix but hasn't used RSC, I can't help but wonder if I still need RSC at all.

What Remix says

Simply search “remix react server components” in Google, and the top result I see is the below post written by the Remix co-founder Ryan Florence:

React Server Components and Remix

This is a great post that not only provides insight behind the scenes but also includes some great live demos and source code. Although this was written before RSC was officially supported by Next.js 13, it appears to be up-to-date based on my understanding(please correct me if I'm wrong). After reading it, it reinforces what I heard at the meet-up:

If I already have Remix, RSC may not be necessary.

The reason is that “Remix can take full advantage of RSC”. The author not only illustrated it through the demo but also conducted real-life testing:

I messed around with these two demos for several days: loading them from my phone while on the freeway (not driving, ofc, but wishing I could drive to Laksa King), waiting for my kids to get out of school on that hill where the cell connections are spotty, and even inside a church building where almost no cellular waves get through.

What a down-to-earth attitude! I followed him on Twitter simply because of this. 😁

This could have been the end of the story several years ago. However, the internet has taught me the importance of considering different points of view to achieve independent thought:

While I agree with everything the author has stated, I believe it is important to consider the different views of the different camps.

What RSC says

One more valuable lesson I've acquired is that when exploring new technology, the most reliable starting point is always the official documentation. In this case, the sole official document for the technology is the RFC available on GitHub:

As per the prerequisites mentioned at the beginning of the RFC, I also watched the following video:

Subsequently, I started to comprehend the motivation and trade-offs of the RSC, as well as why many people don't buy-in.

RSC introduces a new mental model of thinking about your whole web application

Personally, I feel this is the most important and valuable(arguably) thing RSC brings to us. In the new mental model, your whole application is componentized:

RSC

You can now achieve the colocation ( what changes together should stay together) at the component level. At the same time, it allows for composability throughout the entire application, rather than just for the separated frontend. What I find most appealing is that, if done it correctly, the same component can be both rendered on the client and server as needed.

As a result, performance benefits like Zero-Bundle-Size and No Client-Server Waterfalls naturally follow as consequences.

Why people don’t buy-in

Since it’s a new mental model, it needs time and practice to grasp it. It is definitely hard to keep the entire tree of the application in your head all at once, particularly when differentiating between client and server components. But isn’t it the same as when React was first introduced with JSX syntax?

Why people prefer Remix

It also explains why people think Remix is intuitive and easier to understand. Take the example that Dan uses in the video:

function ArtistPage({ artistId }) {
    const stuff = fetchAllTheStuffJustInCase();
    return (
        <AristDetails details={stuff.details} artistId={artistId}>
            <TopTrackers topTracks={stuff.topTracks} artistId={artistId} />
            <Discography discography={stuff.discography} artistId={artistId} />
        </AristDetails>
    );
}
Enter fullscreen mode Exit fullscreen mode

Most developers are so used to this fetch and render pattern. Essentially, it follows the classical API-first pattern, where you plan the data to be fetched from the server at the router layer, retrieve that data, and then pass it down as props to the child components throughout the application.

To make it server render in Remix, all you need to do is just simply move the first line to the loader function:

export async function loader({ request }) {
  return fetchAllTheStuffJustInCase();
}
Enter fullscreen mode Exit fullscreen mode

However, as Dan specified in the video, it’s a kind of compromise for maintenance:

triangle

You might not think so probably because your current mental model works better this way. However, according to the colocation principle mentioned above, or just the more abstract low coupling and high cohesion principle, each component should be responsible for its own data. So, the code is better written this way:

function ArtistPage({ artistId }) {
    return (
        <AristDetails artistId={artistId}>
            <TopTrackers artistId={artistId} />
            <Discography  artistId={artistId} />
        </AristDetails>
    );
}

function ArtistDetail({artistId, children}){
    const details = fetchDetails(artistId);
    // ...
}
Enter fullscreen mode Exit fullscreen mode

That’s exactly what RSC offers for us without compromising user experience or performance.

Finally, Let's not forget that React was originally designed with a client-centric focus. Finding a unified solution without breaking anything existing was a distinct challenge faced and resolved by the React team. As a result, we can now incrementally convert our existing codebase, component by component, to enjoy its benefits. Respect for the React team! 👏

What Remix talks with RSC

After seeing the point of view from both camps, it is interesting and beneficial to observe the discussion between them:

The video is quite long, so I'll leave it to you. I'm looking forward to seeing Remix adopt RSC someday.


Speaking of mental models, the ZenStack toolkit we're building introduces a new one for building your entire backend. It uses the schema file as the single source of truth for your core business logic and leverages code generation to automatically create APIs and front-end queries. Therefore, once the schema is complete, the backend is nearly finished.

Check out our Github repo for more detail:
https://github.com/zenstackhq/zenstack

Top comments (2)

Collapse
 
albert-schilling profile image
Albert

The article is a little misleading regarding Remix. You are missing the important point point that the loader is running on the server, serving as a center stack, between the frontend client and the backend. Meaning you would probably fetch (and cache) a lot of data in the loader function. But then you would aggregate that data to only contain what the client needs before sending it. Combined with nested layout routes, Remix offers a very simple, but powerful architecture to build apps that are optimized for low network traffic, where the client only receives and sends the data it truly needs.

The other point is, that RSC allows to reduce bundle size by running whatever the component needs to run on the server. You can achieve the same with Remix's loader and action functions.

As always, the choice of technology or patterns is a choice of tradeoffs. RSC sound exciting, but then again do the benefits outweigh the added complexity?

Collapse
 
thekingofwit profile image
Brian Barrett

RSC is too much complexity for me. There are simpler solutions that already existed.