What are React Server Components (RSC)?
What React Server Components (RSC) are
React Server Components are components that run on the server, not in the browser. They let React:
- render part of the interface on the server (without shipping JS to the browser);
- pass the result (ready-made HTML + a data tree) to the client;
- combine server and client components in a single tree.
The idea: not all of React has to live in the browser - part of the logic can run on the server, saving the user's resources.
How it works
React now splits components into two kinds:
| Component type | Where it runs | What it can do |
|---|---|---|
| Server Component | On the server | Read files, access a DB, call an API |
| Client Component | In the browser | Use state, effects, events (useState, useEffect) |
Example (on Next.js 13+ or React 18+ RSC)
// app/page.tsx -> this is a Server Component
import ProductList from './ProductList';
export default async function Page() {
const products = await fetch('https://api.example.com/products').then(r => r.json());
return (
<div>
<h1>Product catalog</h1>
<ProductList products={products} />
</div>
);
}This component:
- runs on the server,
- makes a fetch right inside the React component,
- returns a ready-made UI + data to the user.
And all of that without loading any JS code for this component on the client.
Example of a mixed tree (Server + Client)
// app/page.tsx (Server Component)
import ProductList from './ProductList';
export default async function Page() {
const products = await getProducts();
return <ProductList products={products} />;
}// app/ProductList.tsx (Client Component)
'use client'; // important!
import { useState } from 'react';
export default function ProductList({ products }) {
const [filter, setFilter] = useState('');
return (
<>
<input value={filter} onChange={e => setFilter(e.target.value)} />
{products
.filter(p => p.name.includes(filter))
.map(p => <div key={p.id}>{p.name}</div>)}
</>
);
}Here:
Pageis a server component (makes a request to the DB / API);ProductListis a client component (interactivity: filtering, typing, and so on);- React merges them into a single tree automatically.
The main difference from classic SSR
| Feature | SSR (Server Side Rendering) | RSC (Server Components) |
|---|---|---|
| What gets rendered | The whole React code runs on the server -> HTML | Only part of the tree (Server Components) |
| Where the logic lives | Both the server and the client duplicate code | A clean split: server / client |
| Code reuse | Limited | Components can be mixed |
| JS shipped to the client | The whole bundle | Only for client components |
| Performance | Can be slow on large trees | Minimal data and JS on the client |
| Server access | None (SSR cannot use fs or a DB directly) | Yes! Server components can read files, databases, and so on |
How this improves performance
- Less JS on the client
- Server components never end up in the bundle, so the browser does not spend time loading and parsing their code.
- Fewer network requests
- The server can combine requests (fetch / DB) and return ready-made data.
- A faster first render
- The client receives ready-made HTML + serialized props.
- Smooth updates
- React can stream updated pieces of the UI (Streaming SSR).
How the server and client "talk" to each other
RSC works thanks to the React Flight Protocol - a special data format where React serializes the component tree and its props, and the client then "reconstructs" that tree on its side.
A conceptual example:
Server -> React Flight Data (JSON-like structure) -> ClientThe client-side React receives this data and assembles the tree: server parts become ready-made HTML, client parts become interactive React components.
Where you can already use RSC
Support exists in:
- Next.js 13+ (App Router) - the first stable implementation;
- Remix v2+ (in progress);
- React 19 (will be native).
RSC is currently the foundation of the Next.js App Router architecture.
A real-world example from Next.js
// app/page.tsx (Server Component)
import { getProducts } from '@/lib/db';
import ProductCard from './ProductCard';
export default async function Page() {
const products = await getProducts();
return (
<div className="grid">
{products.map(p => (
<ProductCard key={p.id} product={p} />
))}
</div>
);
}// app/ProductCard.tsx (Client Component)
'use client';
export default function ProductCard({ product }) {
const [liked, setLiked] = useState(false);
return (
<div onClick={() => setLiked(!liked)}>
{product.name} {liked ? 'Liked' : 'Like'}
</div>
);
}Page is never loaded on the client -> an instant SSR
ProductCard becomes interactive
React itself optimizes the "server <-> client" boundary
When to use Server Components
Use them if:
- the component only reads data (from an API, a DB, a file);
- it does not use
useState,useEffect,useRef; - it does not react to events;
- it is only needed for SSR/rendering data.
Do not use them if:
- you need an interactive UI (forms, clicks, filters);
- it uses local state, effects, browser APIs (window, document);
- the component depends on user actions.
Summary
| Feature | Description |
|---|---|
| Where they run | On the server (Node.js / Edge) |
| Why they exist | Reduce JS, speed up loading, allow access to server resources |
| Mixing | Can be combined with client components |
| What they don't do | Do not use state, effects, browser APIs |
| Where they work | Next.js 13+, React 19 (built in) |
| Result | Faster rendering, a smaller bundle, a "smart" split of responsibilities |
In simple terms:
React Server Components is a way to make React run part of the UI right on the server, send the user ready-made HTML, and give the client only what it actually needs for interactivity.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.