React Server Components (RSC) are one of the most talked-about additions to React in recent years — and they’ve quickly become a core part of frameworks like Next.js (with App Router), Remix and other SSR React Frameworks.
But let’s get somethings straight before we dive in:
RSC is not a new standard, engine, or framework.
It is low-level React API that enables you to render components entirely on the server, stream the to the client, and hydrate only the parts that need interactivity.
Each framework (like Next.js, Remix, Hydrogen, etc.) builds its own opinionated implementation of RSC - deciding on key points:
- How server rendering is integrated
- How data is fetched
- How streaming works
- How server transfers data to browser
- How caching and revalidation scenarios are handled
…and much more.
So if you are using the Next.js App Router, you are using Next’s RSC implementation specifically, not just “React Server Components” in the abstract.
Why do we need Server Components
Server component aim to solve long-standing web application pain points which were progressing over the time and releases of new tools, frameworks and requirements:
- Less JavaScript shipped to the client
Yes! The problem what we hear for decades and each new tool, framework convinces us that problem is finally solved! But the idea is straightforward - render everything on server and pass to client
- Direct server-side data access
This is still common issues and hot topic for lot’s of developers on “How should I fetch the data and how it affects my page rendering” or “Building Next.js internal API endpoints”, we no longer need it, since components can talk directly to databases, filesystems, or other APIs
- Faster initial loads via streaming
No need to wait for full page rendering, specially when it contains some heavy parts, you can start sending your HTML chunk by chunk as soon as they are ready.
- Improved developer experience
You can write UI and data fetching all together in single place, without worrying about serialization and fetching life cycles.
💡 Does this remind you of something?
Those old days when we just had an Express server with Handlebars (or PHP, or Rails) and rendering whole template on server and just sending it to client.
The difference? Now it is just React - with streaming, selective hydration, and all the modern bells and whistles.
Server Components Trade-Offs
As I already mentioned, you should keep an eye on exact implementation of server components for specific component, because implementation are uniq, there is no standard, so whatever was working for you in one framework might work absolutely differently in another framework.
But besides that we need to consider RSC changes where and how rendering happens:
- Every render of a Server Component happens on the server, not in the browser.
- Browser no longer receives compiled JavaScript with you page bundle which to render on the client - it receives a serialized “Flight” payload which is telling it how to rebuild UI (rsc specific format).
- Client Components still exist in bundle, but they form of hydration islands inside server-render tree.
- Crossing a Server <> Client boundary is serialization cost you pay every time.
These differences bring new pitfalls that we need to consider, and in the meantime it does not remove rest of the pitfalls what we had for SSR apps which we still need to consider as well.
The Real Performance Costs of Server Components
- Flight Payload Overhead (Server <> Client Boundaries)
In RSC, only Client Components hydrate - so any props passed from Server to Client must be serialized onto a Flight payload. Large or deeply nested props props bloat the payload and delay hydration.
// ❌ Large object crossing boundary → huge Flight payload
export default async function ServerPage() {
const bigData = await getLargeDataset(); // thousands of rows
return <ClientChart data={bigData} />; // sent in Flight payload
}
// ✅ Send only what’s needed
<ClientChart data={summaryRows} />
Mental picture:
It’s like shipping an entire warehouse to the customer’s house when they only ordered a single chair — and having them unpack it before they can use anything.
- Streaming Delays for long and heavy components. Suspense order matters!
RSC supports streaming - sending UI chunks to the browser as they are ready.
If a slow server component sites above others without a Suspense boundary, it blocks the whole stream until it finishes.
// ❌ One slow server call holds up the entire page
export default async function Page() {
const data = await slowFetch();
return <MainContent data={data} />;
}
// ✅ Wrap slow sections in Suspense
export default function Page() {
return (
<>
<Header />
<Suspense fallback={<Loading />}>
<SlowSection />
</Suspense>
</>
);
}
Mental picture:
Like waiting for the slowest dish at a restaurant before you’re allowed to eat anything.
- Use client scope explosion
Putting “use client” at the top of a big/shared file promotes that file (and often its imports) to a Client Component, erasing the “no JS for server code” benefit and inflating bundles. Which might be okay for some of the cases, but it still requires additional learning curve for developers and understanding application specifics.
- Community support
RSC changes the rules — and many libraries still aren’t ready for it. Some require "use client" to function, which negates many of RSC’s benefits.
Be prepared: your favorite library might not yet work well in a Server Component environment. For example, most CSS-in-JS frameworks (MUI, Chakra, Stitches, etc.) currently require "use client".
Final Thoughts
React Server Components open the door to faster, leaner, and more maintainable React applications - but they aren’t a silver bullet.
They shift complexity from the browser to the server, introduce new serialization and streaming considerations, and require a different way of thinking about component boundaries.
If you adopt RSC, keep a close eye on:
- Where your Server ↔ Client boundaries are
- What data you pass across them
- How you use Suspense for streaming
- Which libraries truly work well in a server-first model
RSC is a powerful tool - but like any tool, using it effectively means understanding both its benefits and its trade-offs.
Top comments (0)