What's the difference between Server Components and Client Components?
Take a moment.
Say your answer out loud or write it down first — retrieval is what makes it stick. Reveal when you're ready.
Short answer
Server Components run only on the server — they can await data, access secrets, and ship zero JS to the browser, but can't use state or events. Client Components ('use client') also run in the browser, supporting interactivity, and receive serialized props across the boundary.
Detailed explanation
Server Components execute at request/build time: direct database queries, file system access, secret keys — their output streams as HTML/RSC payload without adding bundle weight. They cannot hold state, use effects or browser APIs, or attach event handlers. Client Components are traditional React: interactive, stateful, rendered on the server initially then hydrated in the browser. The boundary rule: importing a Client Component into a Server Component marks everything from there down as client subtree; children passed through remain server-renderable (the children-as-props pattern keeps flexibility). Props crossing the boundary must serialize — functions and class instances don't cross. Strategy: keep pages/layouts server-side and push interactivity to leaf nodes — buttons, forms, carousels — minimizing hydration cost.
Example
// app/products/page.tsx — Server Component (default)
export default async function Page() {
const products = await db.product.findMany(); // direct DB access ✅
return <List items={products} />;
}
// components/AddToCart.tsx — Client Component
'use client';
export function AddToCart({ productId }) {
const [added, setAdded] = useState(false); // state needs 'use client'
return <button onClick={() => setAdded(true)}>{added ? 'Added ✓' : 'Add'}</button>;
}Interview tip
Lead with the capability split (server: data/secrets/no-JS; client: interactivity), then explain boundary propagation and the children-as-props escape hatch.
Common mistakes
- Thinking Client Components skip server rendering entirely.
- Trying to pass event handler functions from server to client components.