React Server Components vs Client Components
Modern frameworks like Next.js utilize React Server Components (RSC). This architecture splits components into two execution scopes: Server Components (render on the server) and Client Components (hydrate on the client).
1. What are React Server Components (RSC)?
By default, all components in modern React setups are Server Components. They are executed entirely on the server to generate a static virtual representation that is streamed to the browser.
Key Benefits
- Zero Client-Side JS: Since Server Components execute on the server, their dependencies are not included in the client JavaScript bundle.
- Direct Backend Access: You can query databases, call backend APIs, and access secure server resources directly inside the component body.
- SEO Friendly: Search engines receive pre-rendered HTML content directly, improving discoverability.
2. Defining Client Components ("use client")
If your component requires client-side interactivity, you must mark it as a Client Component by placing the "use client" directive at the very top of the file:
"use client"; // Marks this module and its imports as client-side
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Clicks: {count}
</button>
);
}3. When to Use Which?
Use this quick reference guide to choose the correct component type:
| Task / Feature | Server Component | Client Component |
| Fetch data directly from databases | Yes | No |
| Access secure backend keys | Yes | No |
| Keep page bundles light (no JS footprint) | Yes | No |
Use event listeners (onClick, onChange) | No | Yes |
Manage local state (useState, useReducer) | No | Yes |
Use lifecycle hooks (useEffect, useLayoutEffect) | No | Yes |
| Interact with browser APIs (window, storage) | No | Yes |
4. Nested Component Composition Rules
You can nest Client Components inside Server Components. However, you cannot directly import and nest a Server Component inside a Client Component.
To pass a Server Component to a Client Component, pass it down as children props:
// Parent (Server Component)
import { ClientWrapper } from "./ClientWrapper";
import { ServerDetails } from "./ServerDetails";
export default function Page() {
return (
<ClientWrapper>
{/* Passed as a children prop, allowing it to render on the server */}
<ServerDetails />
</ClientWrapper>
);
}