Server Components vs Client Components in Next.js 15 — The Complete Guide
Introduction
When I first heard about React Server Components, I had no idea why they mattered. They sounded fancy and cool, but I didn’t understand how they would actually change the way I build apps. Fast-forward to Next.js 15, and understanding the difference between server and client components is now essential if you want to write fast, scalable, modern applications.
In this article, we'll break down the difference, the trade-offs, and most importantly, how to use them together effectively.
What Are Server Components?
Server components are React components that run only on the server. They’re rendered before anything ever reaches the browser, and they don’t ship any JavaScript to the client. This means:
- ✅ Zero JS bundle size for that component
- ✅ Faster initial load and better SEO
- ✅ Direct access to databases, APIs, and secrets
- ✅ Automatic streaming support
If a component doesn’t need interactivity (like state or event listeners), it should probably be a server component.
Example:
1// app/page.tsx
2export default async function HomePage() {
3 const res = await fetch("https://jsonplaceholder.typicode.com/posts");
4 const posts = await res.json();
5
6 return (
7 <div>
8 <h1>Latest Posts</h1>
9 <ul>
10 {posts.map((post: any) => (
11 <li key={post.id}>{post.title}</li>
12 ))}
13 </ul>
14 </div>
15 );
16}
Notice the lack of "use client"
— this is a pure server component. It never runs in the browser.
What Are Client Components?
Client components run in the browser. They’re hydrated with JavaScript and handle all the things server components can’t: state, effects, event listeners, animations, and user interactions.
They must start with the "use client"
directive:
1"use client";
2
3import { useState } from "react";
4
5export default function Counter() {
6 const [count, setCount] = useState(0);
7 return <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>;
8}
If you need useState
, useEffect
, or event handlers, you’re in client territory.
Key Differences
Feature | Server Components | Client Components |
---|---|---|
Runs on | Server (Node.js/Edge) | Browser |
Supports state/effects | ❌ No | ✅ Yes |
Access to backend/DB | ✅ Yes | ❌ No |
Bundle size | ❌ None | ✅ Adds JS |
SEO performance | ✅ Great | ⚠️ Depends |
Interactivity | ❌ None | ✅ Yes |
The Best of Both Worlds
The real magic happens when you combine them. You want most of your app to be server components and only sprinkle client components where interaction is necessary.
1// app/page.tsx (Server)
2import Counter from "./Counter";
3
4export default async function Page() {
5 const data = await fetch("https://api.example.com/data").then(res => res.json());
6
7 return (
8 <div>
9 <h1>{data.title}</h1>
10 <Counter />
11 </div>
12 );
13}
14
15// app/Counter.tsx (Client)
16"use client";
17import { useState } from "react";
18
19export default function Counter() {
20 const [count, setCount] = useState(0);
21 return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
22}
Here, the heavy lifting and data fetching happen on the server, while only the interactive button gets hydrated.
Common Mistakes to Avoid
- ❌ Making everything a client component: This kills performance and makes your app heavier.
- ❌ Using hooks in server components: Hooks like
useState
anduseEffect
don’t work on the server. - ❌ Fetching data on the client unnecessarily: You lose SSR and SEO benefits.
Best Practices
- ✅ Use server components by default.
- ✅ Keep client components small and focused.
- ✅ Pass data from server to client via props.
- ✅ Think about bundle size — server components are free, client ones cost.
Conclusion
Server and client components aren’t rivals — they’re partners. Server components keep your app fast, SEO-friendly, and secure. Client components bring interactivity and life. The secret to building truly modern Next.js 15 apps is knowing how to balance them.
Once you start thinking this way, your apps will not only feel faster but be faster — and your users (and Google) will love you for it.