FrontendReactServer ComponentsNext.jsApp RouterPerformance

React Server Components Explained: When and How to Use Them

A clear, practical explanation of React Server Components — what they are, how they differ from Client Components, and when to use each in Next.js App Router.

Abdur Razzak

Abdur Razzak

Full-Stack Web Developer

July 4, 2024 9 min read

The Mental Model Shift

React Server Components (RSC) represent the biggest shift in React's model since hooks. Before RSC, all React components ran in the browser. With RSC, components can run on the server — they fetch data, render to HTML, and send the result to the client without shipping their JavaScript. This eliminates the client-server waterfall: instead of browser → JavaScript loads → fetch data → render, the server does the fetching and sends ready-to-display content.

Server Components: The Default in Next.js App Router

In Next.js App Router, every component is a Server Component by default. Server Components can be async, use await for data fetching, access server-only resources (databases, file system, environment secrets), and import heavy libraries without adding to the client JavaScript bundle. They cannot use useState, useEffect, event handlers, or browser APIs. Their output is serialized and streamed to the client as HTML and a lightweight description of the UI.

Client Components: Add "use client" at the Top

Add 'use client' at the top of a file to make it a Client Component. Client Components work like traditional React — they can use hooks, handle events, access browser APIs, and maintain state. They are hydrated in the browser from the server-rendered HTML. The 'use client' directive creates a boundary: everything in this file and its imports runs on the client. Choose Client Components for interactive UI: forms, buttons, modals, animations, real-time updates.

The Composition Pattern: Nesting Client in Server

You can nest Client Components inside Server Components but not the reverse. A common pattern: the page-level Server Component fetches data and passes it as props to a Client Component that handles interactivity. The Server Component does the heavy data-fetching work (no loading states, no useEffect); the Client Component handles the interactive UI with that pre-fetched data. This gives you zero client-side waterfall with full interactivity where needed.

When to Use Each

Use Server Components for: data fetching, accessing databases or APIs, displaying static or dynamic content that doesn't need interactivity, importing heavy libraries (markdown parsers, syntax highlighters). Use Client Components for: event handlers (onClick, onChange), useState and useEffect, browser APIs (localStorage, geolocation), real-time subscriptions, animations with Framer Motion. When in doubt, start with Server Components and only add 'use client' when you need it.

Performance Impact

Server Components dramatically reduce the JavaScript shipped to the client. A blog detail page that imports a markdown parser (500KB) can run that parser on the server — the client receives rendered HTML, not 500KB of JavaScript. Combined with Next.js streaming (Suspense boundaries load content progressively), Server Components make React apps feel faster without any manual optimization. Google crawlers also see fully-rendered content immediately, improving SEO.

Share this article

All posts
#React#Server Components#Next.js#App Router#Performance
Abdur Razzak — Full Stack Web Developer
⭐ Top Rated

Upwork Top Rated Developer

Work With a Developer Clients Trust