Back to posts
React Server Components (RSC) – Deep Dive

React Server Components (RSC) – Deep Dive

Ankit Kumar / June 27, 2025

⚛️ React Server Components (RSC) – In-Depth

React Server Components (RSC) are a powerful feature that allow you to render components on the server, reducing client-side JavaScript and improving performance.


📦 What Are React Server Components?

React Server Components are components that run only on the server and send pre-rendered HTML/JSON to the browser.
They help reduce the amount of JavaScript sent to the client, making your app faster and more efficient.


✅ Key Benefits

  • Zero JS bundle cost for server components
  • Access to server-side resources like databases, APIs, environment variables
  • Smaller client bundles = faster page loads
  • Seamless integration with client components

🧱 Component Types in RSC

There are two main types of components in RSC architecture:


🟩 1. Server Components

Default behavior in the Next.js App Router (app/ folder).

✅ Purpose

  • Run entirely on the server
  • Never shipped to the browser
  • Can fetch data, read from filesystem, use secrets

✅ Usage

// app/products/page.tsx
export default async function ProductsPage() {
  const products = await fetchProductsFromDB();

  return (
    <div>
      <h1>Product List</h1>
      <ul>
        {products.map(p => <li key={p.id}>{p.name}</li>)}
      </ul>
    </div>
  );
}

✅ When to Use

  • Heavy data fetching

  • Access to secure data (e.g., DB, API keys)

  • Pages that don't need client interactivity

🟦 2. Client Components

Client Components are React components that run entirely in the browser.
You opt into client-side behavior by adding 'use client' at the top of the file.


✅ Purpose

  • Run in the browser
  • Used for interactivity, state management, and side effects

✅ Usage Example

'use client';

import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>;
}

🔁 How Server and Client Components Work Together

In Next.js (App Router), Server Components can include Client Components, but Client Components cannot import Server Components.


✅ Example: Server → Client Nesting (Valid)

// Server component
import Counter from './Counter'; // 'use client'

export default function Page() {
  return (
    <div>
      <h1>Hello</h1>
      <Counter />  {/* hydrated client-side */}
    </div>
  );
}

🚫 Why Client → Server Nesting Is Not Allowed

You can’t import a server component into a client component because:

  • The browser can't access things like databases, environment variables, or fs

  • Server-only logic would break in the browser

  • Next.js will throw a build error

🧠 Real-World Use Case Example

// app/product/[id]/page.tsx (server)
import ProductDetails from './ProductDetails'; // server
import AddToCartButton from './AddToCartButton'; // client

export default async function ProductPage({ params }) {
  const product = await getProduct(params.id);

  return (
    <div>
      <h1>{product.title}</h1>
      <ProductDetails description={product.description} />
      <AddToCartButton productId={product.id} />
    </div>
  );
}
  • ProductDetails runs only on the server
  • AddToCartButton is interactive and hydrated on the client

🧩 Summary Table

FeatureServer ComponentClient Component
Runs onServer onlyBrowser
Uses useState / useEffect❌ No✅ Yes
Access to DB / secrets✅ Yes❌ No
JS sent to browser❌ No✅ Yes
Interactivity (click, input)❌ No✅ Yes
UsagePages, heavy data logicButtons, forms, modals

💡 Use server components for everything unless interactivity is needed — then break it out into a small client component.