ReactRSCArchitecture

React Server Components: The Mental Model That Finally Clicked

7 min read

When React Server Components landed in Next.js App Router, I spent weeks writing them without fully understanding the model. Then one diagram changed everything. Let me share that mental model.

Two trees, one output

Your app renders two component trees: one on the server (Server Components) and one on the client (Client Components). The server tree can include client subtrees — but not vice versa.

The serialization boundary

Props that cross the server → client boundary must be serializable. No functions, no class instances, no React elements as props (unless using children/slots).

Data fetching belongs at the top

Fetch data as high as possible in the server tree, then pass it down as props. Avoid waterfalls by fetching in parallel with Promise.all.

// app/dashboard/page.tsx (Server Component)
export default async function DashboardPage() {
  const [user, orders] = await Promise.all([
    getUser(),
    getOrders(),
  ])
  return <Dashboard user={user} orders={orders} />
}

Client Components are islands

Think of 'use client' as a boundary marker, not a file-level directive. Everything imported into a Client Component also becomes client-side. Keep the island small.

Once this model clicked, I stopped fighting the framework. RSC is a genuinely better architecture for data-heavy apps — less JavaScript, faster page loads, simpler data flow.

All postsFebruary 28, 2026