Skip to main content

What are React Server Components (RSC)?

1. What React Server Components (RSC) are

React Server Components (RSC) are components that run on the server, not in the browser, while still being integrated into a single React tree with client components.

More simply:

RSC is a way to render part of a React application on the server, while keeping the rest of it interactive on the client, without duplicating logic or hydrating the entire tree as SSR would.


2. How RSC differs from SSR

CriterionSSR (Server-Side Rendering)RSC (React Server Components)
Where it runsThe server generates HTMLThe server generates a React structure (tree)
What is sent to the clientReady-made HTMLA stream of serialized components
What the client does"Brings the HTML to life" (hydration)Merges server and client components
When it runsOn every requestCan be at build time, at fetch time, or partially
Where you can write fetchUsually in getServerSidePropsRight inside the component!

In other words, SSR = "render HTML on the server", while RSC = "render React components on the server without HTML".


3. How the RSC mechanism works

Step 1. Splitting components into types

RSC introduces two types of components:

TypeWhere it runsCan it use Hooks / the DOM
Server ComponentOnly on the serverCannot use useState, useEffect, window, document
Client ComponentIn the browserCan use everything (hooks, the DOM, events, and so on)

Marking it in code:

javascript
// This is a server component (by default) export default async function Page() { const data = await fetch('https://api.example.com/posts').then(r => r.json()); return <PostList posts={data} />; } // This is a client component "use client"; import { useState } from "react"; export function LikeButton() { const [liked, setLiked] = useState(false); return <button onClick={() => setLiked(!liked)}>{liked ? "heart" : "outline heart"}</button>; }

Step 2. A server render returns not HTML but a React Payload

React Server Components do not send HTML. The server generates a stream of serialized React components, called React Flight Data.

An example (simplified):

javascript
[ ["$","div",null,{"children":["Hello from server"]}], ["$","button","client:likeButton",{"children":["like"]}] ]

The client receives this "JSON stream" and assembles the React tree using the RSC runtime.

In other words, the client does not receive HTML, but "instructions" for React on which components to render and which of them are client components.


Step 3. Merging (a hybrid tree)

On the client, React merges two worlds:

  • Server components, already rendered ahead of time (their JS code is not even present on the client),
  • Client components, which load, hydrate, and become interactive.
javascript
<App> |-- <Header /> -> Server Component |-- <PostList /> -> Server Component | |-- <Post /> -> Server Component | `-- <LikeButton /> -> Client Component `-- <Footer /> -> Server Component

This way the client gets a minimal amount of JS - only for LikeButton. Everything else is already rendered on the server and needs no hydration.


4. Benefits of RSC

BenefitWhy it is great
Less JS on the clientThe client does not need the server components' code at all
No double render (as with SSR)RSC does not need HTML hydration - no duplication
HybridityServer and client components can be mixed in a single tree
SecurityServer components never reach the client - keys or API tokens cannot accidentally leak
Faster rendering of large lists / dataLogic and requests run on the server, not in the browser
Compatible with Streaming SSRServer and client parts can be streamed asynchronously

5. An example of RSC in Next.js 13+ (App Router)

javascript
// app/page.tsx - Server Component (by default) import Posts from './Posts'; export default async function Page() { const posts = await fetch('https://jsonplaceholder.typicode.com/posts').then(r => r.json()); return ( <main> <h1>Server-rendered posts</h1> <Posts posts={posts} /> </main> ); }
javascript
// app/Posts.tsx - Server Component import LikeButton from './LikeButton'; export default function Posts({ posts }) { return ( <ul> {posts.map(p => ( <li key={p.id}> {p.title} <LikeButton /> </li> ))} </ul> ); }
javascript
// app/LikeButton.tsx - Client Component "use client"; import { useState } from "react"; export default function LikeButton() { const [liked, setLiked] = useState(false); return ( <button onClick={() => setLiked(!liked)}> {liked ? "liked" : "not liked"} </button> ); }

The whole list of posts renders on the server, while the "like" button is interactive, but loads as a separate JS chunk.


6. RSC != SSR

DifferenceSSRRSC
Output formatHTMLReact Payload (instructions)
HydrationRequiredNot needed
Where the data logic livesIn "getServerSideProps" / an APIRight inside the components
Can it be mixed with client componentsLimitedYes, hybrid
PerformanceBetter than CSR, but requires a double renderEven better - less JS and less HTML

Summary

React Server Components (RSC) are a new foundation for React that:

  • moves part of the logic and rendering to the server,
  • leaves interactivity to the client,
  • removes the need for "hydration" for static parts,
  • reduces the JS size and speeds up page loads,
  • and lets you mix server and client code in a single tree.

If SSR = "the server generates HTML", then RSC = "the server generates a React tree". And that brings React closer to universal rendering - a smart, hybrid model where each component runs wherever it makes the most sense.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.