Understanding React Server Components in Next.js 16
Next.js 16 doubles down on the App Router and React Server Components (RSC). If you are still thinking in terms of getServerSideProps and useEffect-driven data fetching, this post is for you.
What are Server Components?
Server Components render on the server and never ship their JavaScript to the browser. They can read from the database, call internal APIs, or touch the filesystem directly — no client bundle, no hydration cost.
The mental model
Think of your tree as a mix of server-rendered HTML islands and client-rendered interactive widgets. By default everything is a Server Component. You opt into the client with the "use client" directive at the top of a file.
The cheapest JavaScript is the JavaScript you never send.
When to reach for a Client Component
Anything that needs state, effects, browser APIs, or event handlers must be a Client Component. Forms, dropdowns, modals, charts driven by user input — all client. Static product cards, blog content, and dashboards that just read data — server.
Data fetching
Inside a Server Component you can simply await your data layer. No SWR, no React Query, no useEffect. Streaming, caching, and revalidation are handled by Next.js primitives like fetch options and the revalidateTag API.
Trade-offs
RSC is not free. The boundary between server and client is a real cost — props passed across it must be serializable, and you cannot pass functions or class instances. Debugging is also different: a stack trace can cross the network.
Used well, though, Server Components let you ship dramatically less JavaScript while keeping the developer experience close to a normal React app. That is the bet Next.js 16 is making.