Skip to main content

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 typeWhere it runsWhat it can do
Server ComponentOn the serverRead files, access a DB, call an API
Client ComponentIn the browserUse state, effects, events (useState, useEffect)

Example (on Next.js 13+ or React 18+ RSC)

javascript
// 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)

javascript
// app/page.tsx (Server Component) import ProductList from './ProductList'; export default async function Page() { const products = await getProducts(); return <ProductList products={products} />; }
javascript
// 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:

  • Page is a server component (makes a request to the DB / API);
  • ProductList is a client component (interactivity: filtering, typing, and so on);
  • React merges them into a single tree automatically.

The main difference from classic SSR

FeatureSSR (Server Side Rendering)RSC (Server Components)
What gets renderedThe whole React code runs on the server -> HTMLOnly part of the tree (Server Components)
Where the logic livesBoth the server and the client duplicate codeA clean split: server / client
Code reuseLimitedComponents can be mixed
JS shipped to the clientThe whole bundleOnly for client components
PerformanceCan be slow on large treesMinimal data and JS on the client
Server accessNone (SSR cannot use fs or a DB directly)Yes! Server components can read files, databases, and so on

How this improves performance

  1. 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.
  1. Fewer network requests
  • The server can combine requests (fetch / DB) and return ready-made data.
  1. A faster first render
  • The client receives ready-made HTML + serialized props.
  1. 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:

javascript
Server -> React Flight Data (JSON-like structure) -> Client

The 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

javascript
// 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> ); }
javascript
// 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

FeatureDescription
Where they runOn the server (Node.js / Edge)
Why they existReduce JS, speed up loading, allow access to server resources
MixingCan be combined with client components
What they don't doDo not use state, effects, browser APIs
Where they workNext.js 13+, React 19 (built in)
ResultFaster 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 ready
Premium

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