Available for project

MID NOV 2026

(GMT+0)
September 7, 2026/Nextjs/5 min read

React Server Components Explained Without the Jargon

React Server Components change where your website's code runs, and that has real effects on speed and cost. Here is what they are, what they are not, and why business owners should care.

DS
Written byDanish Sohail
React Server Components Explained Without the Jargon

If you have hired a developer in the last couple of years, you have probably heard "server components" mentioned as if the phrase explained something. It does, but not in a way anyone outside a dev team can use. So here is the version I give clients: what React Server Components are, why they make sites faster, and the handful of rules that trip up developers who are new to them.

The problem they solve

For most of React's history, a React website worked like flat-pack furniture. The server sent the browser the instructions — a large bundle of JavaScript — and the browser assembled the page itself. That is flexible, but every visitor pays for it: their phone downloads the code, parses it and runs it before the page is fully usable. On a cheap phone with a patchy connection, that takes a noticeable while.

Server Components flip the default. The server assembles the furniture and delivers it built. The browser receives finished HTML plus only the JavaScript actually needed for the interactive parts.

Server components vs client components

In a framework like Next.js with the App Router, every component is a server component unless you say otherwise. A server component runs only on the server. It can read from a database, call an API with a secret key, or load a file, and none of that code ever reaches the visitor's browser.

A client component is the React most developers already know. It runs in the browser (after also rendering to HTML on the server for the first load), and it can use state, effects, event handlers and browser APIs like localStorage. You need one whenever something responds to the visitor: a menu that opens, a form that validates as you type, a carousel, a map.

Black and white flowchart drawn on a wall, like mapping which components run on the server

The "use client" boundary

You mark a client component by putting "use client" at the top of its file. That line does not just affect one component: it marks a boundary. Everything that file imports becomes part of the client bundle too.

"use client";
import { useState } from "react";

export function MenuToggle({ label }) {
  const [open, setOpen] = useState(false);
  return <button onClick={() => setOpen(!open)}>{label}</button>;
}

The skill is placing that boundary as low in the tree as possible. The header can stay a server component; only the small toggle button inside it needs to be a client component. Put "use client" on the whole layout and you have quietly opted the entire site back into the old model.

Why less JavaScript ships

A blog post page might use a Markdown parser, a syntax highlighter and a date library. With server components, those libraries run on the server and send finished HTML. The visitor downloads none of them. On the content-heavy sites I build, most of each page is server-rendered, and client JavaScript is limited to navigation, forms and a few interactive widgets.

Less JavaScript means less work for the browser's main thread, which directly helps responsiveness. If your site struggles with Interaction to Next Paint, server components are one of the structural fixes; I cover the rest in INP explained. Shipping too much JavaScript also sits near the top of my list of common performance mistakes.

Fetching data on the server

A server component can be async and simply await its data. No loading spinners for the initial content, no API endpoint written just so the browser can ask for data, no keys exposed in the page source. The content is in the HTML when it arrives, which search engines like as much as visitors do; the SEO side is covered in Next.js SEO done right.

It also changes how you think about backends. For many business sites, the server component becomes the thin layer between the page and your CMS or database, which pairs well with an API-first approach to the rest of your systems.

Close-up of screens of code lit by coloured lights, showing React component source files

What cannot cross the boundary

This is the rule that catches developers out most often. When a server component renders a client component, the props it passes have to travel from server to browser, so they must be serialisable. In practice:

  • Fine: strings, numbers, booleans, arrays, plain objects, and a few extras React knows how to handle, such as dates.
  • Not fine: ordinary functions, class instances, database connections, and anything with methods attached.

So you cannot pass an onClick handler from a server component into a client component; the handler has to live in the client component itself. The reverse pattern is useful, though. A client component can accept server components as children, so a client-side accordion can wrap content that was rendered on the server.

Server actions, briefly

There is one kind of function that can cross the boundary: a server action. Mark an async function with "use server" and a form or button in a client component can call it directly. It runs on the server, can write to your database, and returns a result. For contact forms, newsletter sign-ups and admin tools, it removes a lot of plumbing.

Treat every server action like a public API endpoint, because that is what it is. Validate the input and check the user's permissions inside the action, every time.

Common mistakes

  1. "use client" everywhere. Usually added to silence an error message. It works, and it throws away most of the benefit.
  2. Importing server-only code into a client file. A database helper pulled into a client component either fails to build or misbehaves because its environment variables do not exist in the browser. The server-only package turns that mistake into a clear build error.
  3. Using hooks in server components. useState, useEffect and context all need a client component.
  4. Fetching in the browser out of habit. If the data does not depend on what the visitor does, fetch it on the server.

What it means if you own the website

You do not need to understand the mechanics to benefit from them. What you should expect:

  • Faster pages on real phones, because visitors download and run less code. Speed pays back in ways that are easy to underestimate; I tallied them in the hidden ROI of a fast website.
  • Lower hosting costs when caching is done well, since server-rendered pages can often be generated once and served many times. Whether a page should be static or dynamic is still a real decision, as I explain in static vs dynamic websites.
  • Simpler architecture, with fewer separate APIs to build, secure and maintain.

The caveat is skill. Server components reward developers who understand where their code runs. If you are commissioning a build, ask how they decide what becomes a client component; the answer tells you a lot. The wider picture of what the framework changes is in Next.js App Router for business websites.

Want a site that is fast because of how it is built, not because of a plugin? Tell me what you are planning or look through my recent builds.