React Server Components

React Server Components (RSC) are React components that run only on the server — at build time or per request — and send their rendered output to the browser as a serialized component tree, without shipping their code or dependencies as JavaScript. They can be async, read directly from databases and files, and keep secrets on the server. Interactive parts of the UI remain Client Components, marked with "use client".

RSC became stable in React 19 and is the default model in the Next.js App Router, with support in other frameworks like React Router and Waku. It changes how you think about React apps: instead of fetching data in the browser after the page loads, most data fetching moves into components that render on the server, and only the interactive islands hydrate in the browser.

TL;DR

Quick Example

A server component page that queries the database, streams a slow section, and renders an interactive client component:

Core Concepts

RSC vs SSR

Frameworks combine both: the first request gets HTML generated from server and client components, and subsequent navigations fetch RSC payloads.

The Server/Client Boundary

"use client" at the top of a file marks it — and everything it imports — as client code. Rules that follow:

What Goes Where

Server Actions

Functions marked "use server" become endpoints that the client can call. They integrate with <form action={fn}>, useActionState, and useFormStatus for progressive enhancement. Treat every action as a public API endpoint: validate input and check authorization inside it.

Streaming and Suspense

Wrapping slow parts in <Suspense> lets the server send the rest of the page immediately and stream the slow parts as they resolve. Loading states become part of the component tree rather than separate spinners in effects.

Caching

Frameworks cache RSC results and data fetches to avoid repeated work. In Next.js this includes request memoization, the data cache, and full-route caching, controlled by options such as revalidate, revalidatePath, and revalidateTag. Understand your framework's caching defaults before shipping.

Best Practices

Default to Server Components

Add "use client" only where interactivity is needed, and push it as far down the tree as possible so small leaf components hydrate instead of whole pages.

Fetch Data Where It's Used

Colocate queries in the Server Components that render them; frameworks dedupe identical requests within a render.

Avoid Waterfalls

Start independent fetches in parallel (Promise.all) or split them into sibling Suspense boundaries.

Validate and Authorize in Server Actions

Parse inputs with a schema library like Zod and check the user's permissions every time.

Mark Server-Only Modules

Import the server-only package in modules containing secrets so accidental client imports fail at build time.

Common Mistakes

"use client" at the Top of the Tree

Marking a root layout as client turns the entire app into client components, losing RSC benefits.

Passing Functions or Class Instances as Props

Non-serializable props can't cross the boundary. Pass data, or use Server Actions for callbacks.

Leaking Secrets Through Props

Everything passed to a Client Component ends up in the browser. Pass only the fields the UI needs.

Treating Server Actions as Private

They're callable over HTTP by anyone who finds them. Authenticate and validate.

Surprised by Caching

Stale data after mutations usually means a missing revalidation call or misunderstood cache defaults.

FAQ

What are React Server Components?

Components that render exclusively on the server and send a serialized result to the client, so their code and dependencies don't add to the browser's JavaScript bundle.

How are Server Components different from SSR?

SSR renders all components to HTML on the server and then hydrates them all in the browser. Server Components never hydrate; only Client Components ship JavaScript.

Can I use hooks in Server Components?

No. State and effect hooks like useState and useEffect only work in Client Components. Server Components can be async and await data directly.

Do I need Next.js to use Server Components?

You need a framework or bundler integration that supports RSC. Next.js App Router is the most common; React Router, Waku, and others also support it.

Are Server Actions secure?

They're as secure as any API endpoint you write. Frameworks add protections like origin checks, but you must still validate inputs and authorize users inside each action.

Related Topics

References