Server Components
Components that run only on the server and stream their result to the browser.
They can be async, read databases and secrets, and add nothing to the client bundle.
Frontend
Server Components render on the server, can read data directly and send no JavaScript; Client Components hydrate in the browser so they can use state, effects and event handlers.
Components that run only on the server and stream their result to the browser.
They can be async, read databases and secrets, and add nothing to the client bundle.
Components marked with "use client" that render on the server and hydrate in the browser.
They use useState, effects, browser APIs and event handlers, and their code ships to the client.
| Aspect | Server Components | Client Components |
|---|---|---|
| Runs in | Server only | Server render + browser |
| JS sent | None | Component code |
| State & effects | No | Yes |
| Direct data access | Yes (async) | Via props, fetch or actions |
| Use for | Data, layout, static content | Interactivity |
Server Components run only on the server, can be async, read data directly and send no JavaScript to the browser. Client Components, marked with 'use client', also render on the server for HTML but then hydrate in the browser so they can use state, effects and event handlers.
Server Components. Every component in the app directory is a Server Component unless its module, or a module that imports it, starts with the 'use client' directive.
When it uses state or effect hooks, event handlers like onClick, browser-only APIs such as window or localStorage, or libraries that depend on them, such as many animation or chart libraries.
Not directly; anything imported into a client module becomes client code. Instead, pass the Server Component as children or a prop from a Server Component parent, so it is rendered on the server and slotted in.
Yes. That is the normal pattern: a Server Component fetches data and renders an interactive Client Component, passing serialisable props.
Only serialisable values: strings, numbers, booleans, plain objects and arrays, Dates and a few others, plus Server Functions. Functions, class instances and symbols cannot be passed to Client Components.
Yes, during the initial page load they are prerendered to HTML on the server, then hydrated in the browser. 'Client' means their code also ships to and runs in the browser.
Server Components can await database queries or fetch directly in the component body. Client Components get data through props, through Server Functions, or by fetching from the browser with a library like TanStack Query.
Server Component code and its dependencies never reach the browser, so heavy libraries used only for rendering, such as markdown or syntax highlighters, add no JavaScript. Client Components add their code to the bundle.
At the top of the module that is the entry point to interactivity, as low in the tree as practical. Everything that module imports becomes client code, so marking a large parent makes the whole subtree client-side.
Practise every comparison in your dashboard.
Start learning