React Server Components Deep Dive
React Server Components (RSC) are the most significant change to React since hooks. They fundamentally change how you think about data fetching, component composition, and bundle size. Here is how they actually work under the hood.
Server vs Client Components
Server Components run on the server and send rendered HTML to the client. They can access databases, file systems, and server-only APIs directly. They contribute zero bytes to the client JavaScript bundle. Client Components run in the browser and handle interactivity: event handlers, state, effects, and browser APIs. By default in Next.js App Router, all components are Server Components unless you add the use client directive.
The Rendering Pipeline
When a request arrives, the server renders Server Components into a special format called RSC Payload — a serialized tree of React elements, not HTML. Client Components are referenced by module ID, not rendered on the server. The client receives the RSC Payload, resolves Client Component references, and hydrates only the interactive parts. This is why Server Components reduce JavaScript — the server code never reaches the client.
Composition Patterns
Server Components can import and render Client Components. Client Components cannot import Server Components, but they can accept Server Components as children props. This pattern is how you compose server-rendered content inside interactive shells: a Client Component wrapper with use client provides a dropdown menu, and the Server Component content inside it is rendered on the server and passed as children.
Data Fetching
Fetch data directly in Server Components with async/await. No useEffect, no loading states, no data fetching libraries. The server waits for the data and renders the component. Use Suspense boundaries to stream parts of the page as they become ready, showing fallback UI for slower data sources while fast sections appear immediately.
Common Pitfalls
The most common mistake is marking too many components as use client. Only components that use state, effects, or event handlers need the directive. A component that just renders props does not need use client even if a parent is a Client Component. Another pitfall is importing a large library in a Server Component and accidentally including it in a Client Component through a shared file — use separate files for server and client utilities.
Related Posts
Sponsor Our Newsletter
Reach thousands of developers who are actively evaluating AI tools, MCP servers, and dev infrastructure. Our weekly newsletter goes to engaged technical decision-makers.
All sponsored content is clearly labeled per our editorial policy.