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
Full-Stack Web Developer
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.
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.
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.
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.
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.
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.