React Server Components represent the most significant architectural change to
React since hooks. The core idea: components run on the server by default.
You only ship client-side code when you explicitly opt in with the 'use client'
directive.
The old mental model
Browser → Download JS bundle → Render components → Fetch data → Re-render
The RSC mental model
Server → Render components → Fetch data (co-located with your DB) → Stream HTML
Browser → Hydrate only the interactive islands
What this means in practice
Data fetching moves to the server. You can await a database query
directly inside a component. No useEffect, no useState, no loading
spinners for data that's already resolved before the first byte hits the wire.
Bundle size drops dramatically. A component that only renders markup and
never needs interactivity ships zero JavaScript to the client.
Composition changes. You compose server and client components like Lego
blocks. Server components can render client components as children, but not
the other way around. This "server outer, client inner" pattern becomes
second nature.
The 'use client' boundary
Marking a component with 'use client' doesn't mean it only runs on the client.
It means it runs on both the server (for the initial HTML) and the client
(for hydration and interactivity). The directive is a boundary marker, not a
runtime exclusion.
Key takeaway
Stop thinking of your app as a client-side SPA that happens to use a server.
Start thinking of it as a server-rendered app with islands of interactivity.
This is the inversion that makes RSCs click.