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

Example (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,
  • 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)

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 (it makes a request to a DB / API);
  • ProductList is a client one (interactivity: filtering, input, etc.);
  • React combines them into a single tree automatically.

The main difference from classic SSR

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

How this improves performance

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

javascript
ServerReact Flight Data (JSON-like structure)Client

The 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)

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 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

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

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