# React Server Components > Server-rendered components that ship zero JS to the browser. Frontend architecture guidance from fearchitect, written by Abas Turabli and last reviewed 2026-06-21. Source: https://fearchitect.com/topics/react-server-components Use it as reference for the task at hand. Before changing code, check this guidance against the codebase: where the code already makes a different, deliberate choice, flag the conflict instead of rewriting it. Library APIs move faster than this guide, so confirm exact signatures in the official docs linked at the end. ## Summary React Server Components (RSC) run only on the server — they fetch data, render to a wire format, and send the result to the client without bundling their code into the JS payload. Static subtrees add no client JS; interactive parts opt in with `"use client"`. Default in the Next.js App Router. ## Definition RSC splits the component tree into two worlds: server components run on the server (or at build time), have direct access to databases and secrets, and emit React's wire format — not HTML. Client components, marked `"use client"`, are the interactive islands that hydrate in the browser. The boundary is explicit: any component that touches `useState`, `useEffect`, or browser APIs must be a client component. Props crossing the boundary must be serializable — strings, numbers, plain objects, arrays — not functions or class instances. Large, data-heavy subtrees stay server-side, shrinking the JS bundle the browser must parse and execute. ## Diagram ```mermaid sequenceDiagram participant Browser participant Server Browser->>Server: GET /products/42 Server->>Server: Render server component tree (async, DB access) Server-->>Browser: HTML shell + RSC payload (streamed) Browser->>Browser: Hydrate client islands only ("use client" subtrees) ``` Server renders the full tree and streams the RSC payload; only client-component islands hydrate in the browser. ## Request lifecycle ### 1. Server render Next.js renders the server component tree on the server. Each `async` component `await`s its own data — DB queries, ORM calls, or internal fetches — directly, with no API route needed. ### 2. RSC payload React produces an RSC payload — a compact wire format encoding the component tree and streamed data — not HTML. This is sent to the client alongside the HTML shell. ### 3. Client reconcile React's runtime on the client reconciles the payload into the existing DOM. Server components never re-render in the browser; only `"use client"` subtrees hydrate. ### 4. Props serialization Props flow one-way: server to client, serialized in the payload. Client components can import server components only as props (children or slots), not as direct imports — the bundler enforces this. ## Server component with a client island The server component fetches data directly; `AddToCartButton` is the only code shipped to the browser. Props passed across the boundary are plain serializable values. **ProductPage (server) + AddToCartButton (client)** ```tsx // app/products/[id]/page.tsx — server component (no "use client") export default async function ProductPage({ params, }: { params: Promise<{ id: string }>; }) { const { id } = await params; // Runs on the server — never exposed to the browser. const product = await db.product.findUnique({ where: { id } }); return (

{product.name}

{product.description}

{/* Client island — only this subtree ships JS */}
); } // components/AddToCartButton.tsx "use client"; // marks the server/client boundary import { useState } from "react"; export function AddToCartButton({ productId, price, }: { productId: string; price: number; }) { const [added, setAdded] = useState(false); return ( ); } ``` `db` never reaches the browser. `"use client"` is the boundary directive — everything above it stays server-only. Props are serializable strings and numbers. ## Tradeoffs **Pros** - Zero JS shipped for server-only components — smaller bundles, faster parse. - Data fetching co-located with the component; no API route required. - DB credentials and secrets stay on the server by default. - Async server components eliminate client-side data-fetching waterfalls. **Cons** - Props crossing the boundary must be serializable — no functions. - No `useState`, `useEffect`, or browser APIs inside server components. - Two component types add mental overhead for teams new to RSC. - Server render and client hydration are separate phases — harder to debug. ## Watch out: Common pitfalls Passing non-serializable props (functions, class instances) across the boundary crashes at runtime. Marking too many components `"use client"` negates bundle savings — keep islands small and at the leaves. Context providers must be client components, so server components cannot consume React context. In Next.js 15+, `params` and `searchParams` are async Promises and must be awaited. ## Key terms - **RSC payload**: React's compact wire format encoding the server-rendered component tree, streamed to the client. - **"use client"**: Directive marking the file as a client component boundary; bundler includes it in the JS bundle. - **Serializable props**: Props that survive JSON serialization: strings, numbers, plain objects, arrays — not functions. - **Client island**: A `"use client"` subtree embedded inside a server-rendered tree that hydrates independently. ## Related topics - [Streaming SSR](https://fearchitect.com/topics/streaming-ssr.md): Flush the HTML shell immediately, then stream the rest as Suspense resolves. - [Partial Prerendering (PPR)](https://fearchitect.com/topics/partial-prerendering.md): Static CDN shell plus dynamic Suspense holes in one response. - [Hydration Strategies & Islands](https://fearchitect.com/topics/hydration-and-islands.md): Pay JS cost only for interactive regions, not the whole page. - [Rendering Strategies: CSR / SSR / SSG / ISR](https://fearchitect.com/topics/rendering-strategies.md): Where and when HTML is generated: build, request, browser, or revalidated. - [Resumability (Qwik)](https://fearchitect.com/topics/resumability-qwik.md): Skip hydration by serializing state and listeners directly into HTML. - [Component Architecture & Project Structure](https://fearchitect.com/topics/component-architecture.md): Structuring components so composition beats configuration. ## Further reading - [React — Server Components](https://react.dev/reference/rsc/server-components) - [Next.js — Server and Client Components](https://nextjs.org/docs/app/getting-started/server-and-client-components) - [React — "use client"](https://react.dev/reference/rsc/use-client)