Server Components have been stable in Next.js for over a year. Most explanations of them focus on bundle size and performance. That’s not wrong, but it misses the more interesting shift.
The Old Mental Model
In a React app before RSC, the boundary was simple: server renders HTML once for the initial load, then React takes over. Everything after that is client-side. Data fetching lives in useEffect or a library like React Query, which means it happens after the component mounts — a waterfall.
What Changed
Server Components run on the server and never ship to the client. They can be async. They can await database queries or API calls directly.
// This component never reaches the browser
export default async function PostList() {
const posts = await db.query('SELECT * FROM posts ORDER BY date DESC');
return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
}
No useEffect. No loading state for the initial render. No data fetching library. The component runs once on the server and sends HTML.
The Boundary Is Explicit Now
The interesting shift is that you now think explicitly about where code runs. Client Components opt in with 'use client'. Everything else is a Server Component by default.
This forces a question you didn’t have to ask before: does this component need to be interactive? If not, it doesn’t need to be a Client Component. The browser never downloads it, never parses it, never runs it.
What It Means in Practice
Server Components work well for anything that fetches data and renders it. Client Components are for anything with state, event handlers, or browser APIs.
The composition model is the thing to understand: Server Components can render Client Components, but Client Components cannot render Server Components. The boundary only flows one direction.
What It Doesn’t Fix
RSC doesn’t eliminate the need to think about data fetching. It moves some of it to the server, but the decisions — what to fetch, when, how to handle errors — are still yours.
It also adds complexity. A codebase with mixed Server and Client Components has more rules to keep track of. The tradeoff is worth it at scale, less clear for smaller projects.