Engineering

What Server Components Actually Changed

Beyond the discourse: where the rendering boundary belongs, what it does to bundle size and data fetching, and the mistakes that follow from misplacing it.

Purushottam Kumar Suman
Purushottam Kumar Suman
Founder & CEO, Drema AI
9 min read
Developer writing code at a desktop monitor

The argument about server components generates more heat than clarity. The practical change is narrow and consequential: you now choose, per component, whether code ships to the browser at all. Most of the confusion comes from teams drawing that boundary in the wrong place.

01

The boundary is a shipping decision

A server component's code never reaches the browser. Its dependencies do not either. That is the whole benefit: a date library, a markdown parser, a syntax highlighter used only to render output can stay entirely on the server. The saving is not marginal — it is often the majority of a bundle.

The client boundary is not an architecture debate. It is a decision about what gets downloaded.

02

Push the boundary down, not up

The common mistake is marking a whole page as a client component because one button needs an onClick handler. That ships the entire subtree. The correct move is to extract the interactive piece into its own small client component and leave everything around it on the server.

03

Data fetching moves next to the data

Fetching in the component that renders the data removes an entire category of plumbing — no loading state threaded through props, no effect synchronising with a request, no waterfall caused by a child needing data the parent did not know to fetch. Components become independently understandable, which is a larger maintainability gain than it sounds.

Server by defaultOnly opt into the client where needed
Small client leavesInteractivity at the edges of the tree
Fetch where you renderNo prop-threaded loading states
Stream slow partsSuspense boundaries around them
04

Streaming changes what slow means

With Suspense boundaries, a slow section no longer blocks the page. The shell renders immediately and slow regions fill in. This reorders the optimisation question: rather than making everything fast, decide what must appear instantly and let the rest stream.

05

The failure modes to watch

Two recur. Sequential awaits in a server component create a waterfall that a parallel fetch would avoid. And accidentally passing a large object across the boundary serialises it into the payload, silently negating the bundle saving you were pursuing. Both are visible in the network payload if you look.

06

Is it worth adopting?

For content-heavy and commerce applications where first-load speed and search visibility matter commercially, clearly yes. For an internal dashboard behind a login where everything is interactive, the benefit is smaller and the migration cost is real. It is a tool with a domain, not an upgrade everyone owes.

ReactNext.jsServer ComponentsSuspenseStreamingBundle size
Purushottam Kumar Suman
Written by
Purushottam Kumar Suman
Founder & CEO, Drema AI

Founder and CEO of Drema AI. Builds AI systems, SaaS platforms and industry software — and writes about what actually survives production.

CTA Background

Got a problem like this one?

Bring it to a call with a founder.You will get a straight answer, including when the answer is no.

View Our Work
AI-First Engineering
Secure & Scalable
Built to Deliver Impact