React Server Components vs Client Components: A Practical Decision Guide
"use client" or not? A simple, practical framework for deciding what runs on the server and what runs in the browser in a Next.js App Router project — with the mistakes that quietly bloat your JavaScript bundle.
React Server Components changed the most basic decision in a React project: where does this component run? Get it right and your pages ship dramatically less JavaScript. Get it wrong — usually by adding 'use client' at the top of everything — and you lose the main benefit of the Next.js App Router while keeping all of its complexity.
The 30-second version
Server Components run only on the server. They can fetch data directly, use secrets safely, and send zero JavaScript to the browser.
Client Components run in the browser (and are pre-rendered on the server for the first paint). They can use state, effects, event handlers and browser APIs — and every line of them is downloaded by your visitors.
In the App Router, components are Server Components by default. You opt into the client, not out of it.
A simple decision rule
Ask one question: does this component need to respond to the user in the browser?
Needs
useState,onClick,useEffect, form interactivity, animations, or browser APIs → Client Component.Only displays data — product lists, blog posts, dashboards' read-only panels, marketing sections → Server Component.
A page that is 90% display with one interactive widget? Keep the page a Server Component and make only the widget a Client Component, imported inside it. This "islands" pattern is where most of the bundle savings live.
The mistakes I see in real codebases
'use client'on a layout or page "just in case" — it pulls the entire subtree's dependencies into the browser bundle.Fetching data in Client Components with
useEffectwhen the parent could fetch on the server — slower, more spinners, worse SEO.Passing huge objects as props from server to client — everything you pass gets serialised and shipped. Pass only the fields the interactive part needs.
Keeping secrets near the client boundary — API keys belong in Server Components, Server Actions or route handlers, never in client code.
What this means for performance and SEO
Server-rendered content arrives as HTML: search engines index it reliably, and users see content before JavaScript loads. Teams migrating properly from the Pages Router routinely cut their client JavaScript substantially — which flows straight into better Core Web Vitals. If performance is your pain point, pair this with the fixes in why your Next.js site is slow .
Bottom line
Default to the server. Add 'use client' at the smallest possible leaf, exactly where interactivity lives. That single habit is the difference between an App Router project that feels modern and one that quietly ships a 2020-sized bundle.
Building a new Next.js app, or migrating an existing one? See my services or start a project.