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 sending 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 types:
| Component type | Where it runs | What it can do |
|---|---|---|
| Server Component | On the server | Read files, access a database, call an API |
| Client Component | In the browser | Use state, effects, events (useState, useEffect) |
Example (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,
- does a fetch right inside the React component,
- returns already-ready UI + data to the user.
And all of this happens without loading this component's JS code 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 (it makes a request to a DB / API);ProductListis a client one (interactivity: filtering, input, etc.);- React combines them into a single tree automatically.
The main difference from classic SSR
| Feature | SSR (Server Side Rendering) | RSC (Server Components) |
|---|---|---|
| What gets rendered | The entire React code runs on the server → HTML | Only part of the tree (Server Components) |
| Where the logic lives | Both server and client duplicate code | A clean split: server / client |
| Code reuse | Limited | Components can be mixed |
| JS sent to the client | The whole bundle | Only for client components |
| Performance | Can be slow with large trees | Minimal data and JS on the client |
| Access to the server | None (SSR cannot use fs or a DB directly) | Yes! Server components can read files, databases, etc. |
How this improves performance
- Less JS on the client
- Server components do not end up in the bundle, so the browser doesn't waste time downloading 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 already-ready HTML + serialized props.
- Smooth updates
- React can stream updated pieces of the UI (Streaming SSR).
How the server and client "communicate"
RSC works thanks to the React Flight Protocol: a special data format in which React serializes the component tree and its props, and the client then "reconstructs" that tree on its side.
Conceptually, for example:
Server → React Flight Data (JSON-like structure) → ClientThe client-side React receives this data and joins the tree: the server parts become ready-made HTML, the client parts become interactive React components.
Where you can already use RSC
Supported by:
- Next.js 13+ (App Router): the first stable implementation;
- Remix v2+ (in development);
- React 19 (will be native).
RSC is currently the foundation of the Next.js App Router architecture.
Example from Next.js (a real case)
// 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 isn't loaded on the client → an instant SSR
ProductCard becomes interactive
React itself optimizes the "server ↔ client" boundary
When to use Server Components
Use one if:
- the component only reads data (from an API, a DB, a file);
- it doesn't use
useState,useEffect,useRef; - it doesn't react to events;
- it's needed only for SSR/rendering data.
Don't use one 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 | To reduce JS, speed up loading, allow access to server resources |
| Mixing | Can be combined with client components |
| What they don't do | Don't use state, effects, browser APIs |
| Where they work | Next.js 13+, React 19 (built in) |
| Result | Faster render, smaller bundle, "smart" separation of responsibilities |
In simple terms:
React Server Components is a way to make React run part of the UI directly on the server, send the user already-ready HTML, and send the client only what's really needed for interactivity.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.