Where Your Code Runs

Every file under app/ is a Server Component until something says otherwise. There is no directive and no opt-in: a component is a Server Component because no client module imports it. Its code runs on the server — at build time for a prerendered route, per request for a dynamic one — and is never sent to the browser.

The name Client Component is the one that misleads. A Client Component runs in both places: once on the server to produce HTML, and again in the browser to hydrate it. Prove it with two logs.

A Server Component and the client child it rendersJavaScript
// app/page.js
import Counter from "./counter";
export default function Home() {
  console.log("[server] Home rendered at", new Date().toISOString());
  return <main><h1>Boundary demo</h1><p>Rendered on the server.</p>
    <Counter start={3} /></main>;
}
// app/counter.js
"use client";
import { useState } from "react";
export default function Counter({ start }) {
  const [n, setN] = useState(start);
  console.log("[client] Counter rendered, n =", n);
  return <button onClick={() => setN(n + 1)}>Clicked {n} times</button>;
}

Run npx next build: the terminal prints both lines while it prerenders the route, because the client component's render function ran on the server too. Then npx next start, open the page in Chromium 4,389 and click twice — the browser console shows only the client half, once per state update.

Output of 18
[server] Home rendered at 2026-09-22T05:19:01.679Z   <- next build, in the terminal
[client] Counter rendered, n = 3
log: [client] Counter rendered, n = 3   <- next start, in the browser console
log: [client] Counter rendered, n = 4
log: [client] Counter rendered, n = 5

[server] Home rendered never reaches the browser, and neither does the source of Home — not the timestamp, not an API key, not a database query.

What runs where, and what the browser downloads
Runs on the server Runs in the browser Ships to the browser
Server Component Yes No No
Client Component Yes Yes Yes

So a Server Component may do things a component has never been allowed to do: be async and await in its body, open a MongoDB 1,815 connection (MongoDB), call the Express 24,430 API of Express.js with a secret header. What it may not do is hold state, register an effect or attach an event handler — none of that code is ever alive in a browser to respond.