The New Model
The Server Components shift
Lesson 1 of 4
What you'll learn
- Understand what changed from the all-client model you remember
- Read a Server Component vs. a Client Component island
- Know the rule for choosing which is which
Around React 17 everything was a client component: the whole tree hydrated in the browser whether it needed interactivity or not. The defining change since is React Server Components (RSC) — components that render on the server and ship zero JavaScript. In the modern app (Next.js App Router, the model you'd meet first), components are server by default; you opt into the client only for interactive islands.
// Server Component (default) — runs on the server, ships no JS.
// It can await data directly: no useEffect, no client fetch.
export default async function CoursePage() {
const course = await db.courses.find("react");
return <LessonList course={course} />;
}
// Client Component — opt in for interactivity.
"use client";
import { useState } from "react";
export function Bookmark() {
const [saved, setSaved] = useState(false);
return <button onClick={() => setSaved(!saved)}>{saved ? "★" : "☆"}</button>;
}
The rule
Server by default. Drop to "use client" only when you need state, effects, event handlers, or browser APIs. Everything else stays on the server, where it's faster, safer, and ships nothing to the browser.
Why this matters for you
This inverts the 2021 default. Then, "less JS" meant code-splitting a client bundle. Now the bundle only contains the interactive islands — so a content-heavy page can ship almost no JS at all.
The challenge tallies how much JavaScript a tree ships once only the client islands count. Run it.
Run it. Only client components (and their children) add to the bundle; server components ship nothing.
Which of these forces a component to be a Client Component?
Next: what hooks look like now that the compiler does the memoizing for you.
Saved on this device. Sign in to sync your progress everywhere.