React Server Components: Zero-JS Server Rendering
React Server Components (RSC) allow you to render components on the server and exclude their code from the client JavaScript bundle. In frameworks like Next.js App Router, components are Server Components by default. Use 'use client' only for truly interactive parts. This dramatically reduces bundle size, hydration cost, and main-thread work.
Server Components = chef prepares and plates the food in the kitchen (server). Only the final plated dish is sent through the window. Client Components = the waiter (browser) gets some tools and instructions to handle final touches like seasoning or customer requests. You only ship tools for the parts that actually need them.
1Server Components
Run exclusively on the server. Can fetch data, access databases, read files, and keep secrets safe. Their output (HTML + serialized props) is sent to the client with no JavaScript cost.
export default async function ProductsPage() {
const products = await db.products.findMany();
return <ProductList products={products} />;
}2Client Components
Marked with 'use client'. Handle state, effects, event handlers, and browser APIs. Only these parts ship JavaScript and hydrate.
'use client';
export default function Button() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}3Composition & Boundaries
Server Components can render Client Components. Data flows from server to client via props. Keep client boundaries small and intentional.
4Data Fetching Advantages
Fetch directly in Server Components with native async/await. Parallel fetching with Promise.all is natural. No need for client-side loading states in many cases.
| Property | Server Component | Client Component |
|---|---|---|
| Allowed | async/await, database access | hooks, events, effects |
| Js Cost | Zero | Full bundle + hydration |
| Use Case | Data fetching, static/read-only UI, server-only logic | Interactivity, local state, browser APIs |
| Not Allowed | useState, useEffect, onClick | Direct server-only APIs |
Server Component
Allowed
async/await, database access
Js Cost
Zero
Use Case
Data fetching, static/read-only UI, server-only logic
Not Allowed
useState, useEffect, onClick
Client Component
Allowed
hooks, events, effects
Js Cost
Full bundle + hydration
Use Case
Interactivity, local state, browser APIs
Not Allowed
Direct server-only APIs
Common questions
- ›“What are React Server Components and how do they differ from Client Components?”
- ›“How does RSC reduce bundle size?”
- ›“Explain data fetching in Server Components.”
- ›“When would you use 'use client' in a Next.js app?”
What interviewers look for
- Clear distinction between RSC and classic SSR
- Understanding of bundle boundary and hydration impact
- Practical composition patterns
- Awareness of trade-offs (complexity vs performance)
Short answer (60 sec)
React Server Components render on the server and do not ship JavaScript to the client. They are the default in Next.js App Router. Use 'use client' only for interactive parts that need state, effects, or browser APIs. This keeps bundles small and reduces hydration cost.
Detailed answer (senior level)
RSC is a paradigm shift: it moves rendering and data logic to the server while keeping only truly interactive code on the client. Server Components can fetch data directly and pass props to Client Components. The real power is in reducing unnecessary client JavaScript. In practice, you keep the shell and data-heavy parts as Server Components and isolate small interactive islands behind client boundaries.
- Putting everything in Client Components out of habit
- Trying to use hooks inside Server Components
- Making overly large client boundaries
- Forgetting that props passed to Client Components must be serializable
- Assuming RSC eliminates all JavaScript
- ✓Server Components = zero client JS for non-interactive UI
- ✓Client Components = only for state, events, and browser APIs
- ✓'use client' creates a boundary in the module graph
- ✓RSC excels at data fetching directly on the server
- ✓Biggest win: dramatically smaller bundles and hydration cost
- ✓Combine with Streaming SSR and Islands for optimal performance
- ✓Measure client bundle size — not just render time