Phil Whittaker

Thoughts on Applied AI in software engineering

Staff Engineer (AI) @ Umbraco

Understanding React Server Components

Deep dive into how RSC changes the way we think about data fetching.

Phil Whittaker10 February 20263 min readreact, performance

The Paradigm Shift

React Server Components represent the biggest architectural change to React since hooks. They fundamentally alter where your components run and how data flows through your application.

Server Components let you write UI that renders on the server — without sending the component code to the client.

This is not SSR. With traditional server-side rendering, your component code still ships to the browser for hydration. Server Components never reach the client at all.

How It Works

The mental model is straightforward:

  • Server Components run only on the server. They can directly access databases, file systems, and internal services.
  • Client Components run on both server (for initial HTML) and client. They handle interactivity — state, effects, event handlers.
// This is a Server Component by default in Next.js App Router
async function PostList() {
  const posts = await db.posts.findMany({
    orderBy: { createdAt: "desc" },
    take: 10,
  });
 
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          <PostCard post={post} />
        </li>
      ))}
    </ul>
  );
}

No useEffect. No loading states for the initial fetch. No API routes to build. The data is right there.

The Composition Pattern

The real power emerges when you compose server and client components together:

// Server Component — fetches data
async function Dashboard() {
  const analytics = await getAnalytics();
 
  return (
    <div>
      <h1>Dashboard</h1>
      {/* Client Component — handles interactivity */}
      <InteractiveChart data={analytics} />
      {/* Server Component — no JS shipped */}
      <RecentActivity />
    </div>
  );
}

This pattern means you ship JavaScript only for the parts that need it. Everything else is just HTML.

Common Pitfalls

When adopting Server Components, watch out for these mistakes:

  1. Adding "use client" everywhere — start without it and only add when you need interactivity
  2. Passing non-serialisable props — server-to-client boundaries can only pass JSON-serialisable data
  3. Importing server-only code in client components — use the server-only package to catch this at build time
  4. Over-fetching at the layout level — fetch data as close to where it's used as possible

Performance Wins

The numbers speak for themselves:

MetricTraditionalWith RSC
JS Bundle245 KB89 KB
Time to Interactive3.2s1.1s
Largest Contentful Paint2.8s1.4s

Less JavaScript means faster pages, better Core Web Vitals, and happier users.

Getting Started

If you're using Next.js 13+ with the App Router, you're already using Server Components. Every component in the app/ directory is a Server Component by default. Embrace that default — you'll write less code and ship faster applications.


Enjoyed this post?

Subscribe to get new posts delivered to your inbox.