React Server Components (RSC)

Server-only components for optimal performance, default in App Router. Ideal for Modern apps, Data-heavy applications, and Secure apps requiring server-side logic.

Server

🌐
Request
Response
πŸ–₯️
Server receives request
Server fetches data
React.renderToReadableStream()
Server renders Server Components
Server serializes RSC payload
Server sends RSC payload

Client

Client receives RSC payload
React.hydrateRoot()
Client hydrates components
✨Page interactive
Benefits x Trade-offs

Benefits

  • β€’Optimal Performance: Server + client components
  • β€’Secure Data Access: Server-side data fetching
  • β€’Reduced Bundle Size: Less JavaScript to client
  • β€’Better SEO: Server-rendered content

Trade-offs

  • β€’Interactivity split: Need to choose server vs client
  • β€’Hydration step: Client components need hydration
  • β€’Learning curve: Understanding server/client boundaries
  • β€’Serialization limits: Can't pass functions/classes
How to implement?

RSC uses Server Components by default in App Router. Server Components cannot import Client Components.

// Server Component (default)
export default async function ServerComponent() {
  const res = await fetch("https://api.example.com/data");
  const data = await res.json();

  return (
    <div>
      <h1>{data.title}</h1>
      <ClientComponent data={data} />
    </div>
  );
}

// Client Component (when needed)
"use client";
import { useState } from "react";

export function ClientComponent({ data }: { data: any }) {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
  • β€’Server Components are async functions (default, no directive needed)
  • β€’Cannot use React hooks in Server Components
  • β€’Add 'use client' directive only when you need interactivity
  • β€’Server Components can fetch data directly, Client Components use hooks