Master Code
On The Go

Learn. Practice. Build.

Home › How-To › Server vs Client Components

Next.js Guide

Server vs Client Components

React Server Components changed how we build React apps. Here's the mental model, the rules, and when to reach for each one.

Quick answer: Default to Server Components — they run on the server, ship no JS, and can fetch data directly. Add "use client" only when you need interactivity, browser APIs, or hooks like useState.

⚡ Quick Comparison

FeatureServer ComponentClient Component
Runs onServerBrowser
Ships JS to browserNoYes
Can fetch data directlyYes (await)No (use useEffect)
useState / useEffectNoYes
Browser APIs (window, localStorage)NoYes
Event handlers (onClick)NoYes
Access to DB / secretsYesNo
Default in App RouterYesNo (needs "use client")
1

Server Component (Default)

Any component without "use client" is a Server Component:

// app/posts/page.tsx
async function getPosts() {
    const res = await fetch('https://api.example.com/posts');
    return res.json();
}

export default async function Posts() {
    const posts = await getPosts();

    return (
        <ul>
            {posts.map(p => <li key={p.id}>{p.title}</li>)}
        </ul>
    );
}

Notice: async function, await fetch directly inside, no useEffect, no loading state.

2

Client Component

Add "use client" at the top when you need interactivity:

// app/components/Counter.tsx
'use client';

import { useState } from 'react';

export default function Counter() {
    const [count, setCount] = useState(0);

    return (
        <button onClick={() => setCount(count + 1)}>
            Count: {count}
        </button>
    );
}

Client Components can use hooks, event handlers, and browser APIs.

3

Mixing Them Together

Server Components can render Client Components as children:

// app/page.tsx — Server Component
import Counter from './components/Counter';

export default async function Home() {
    const data = await fetch('https://api.example.com/stats').then(r => r.json());

    return (
        <div>
            <h1>Total users: {data.users}</h1>
            <Counter />  {/* Client component inside server page */}
        </div>
    );
}

The page runs on the server (fast, secure) and passes data into the Counter — which is interactive in the browser.

4

Passing Server Data to Client

Pass serializable props from server to client:

// app/page.tsx (Server)
import SearchBox from './components/SearchBox';

export default async function Page() {
    const categories = await fetch('https://api.example.com/categories').then(r => r.json());

    return <SearchBox categories={categories} />;
}

// app/components/SearchBox.tsx (Client)
'use client';
import { useState } from 'react';

export default function SearchBox({ categories }) {
    const [query, setQuery] = useState('');
    const filtered = categories.filter(c =>
        c.name.toLowerCase().includes(query.toLowerCase())
    );

    return (
        <div>
            <input value={query} onChange={(e) => setQuery(e.target.value)} />
            <ul>{filtered.map(c => <li key={c.id}>{c.name}</li>)}</ul>
        </div>
    );
}

Server fetches data. Client handles interaction. Best of both.

5

Passing Server Components as Children

Client Components can't import Server Components directly, but they can receive them as children:

// app/page.tsx (Server)
import Modal from './components/Modal';
import UserList from './components/UserList';

export default function Page() {
    return (
        <Modal>
            <UserList />  {/* Still a Server Component */}
        </Modal>
    );
}

// app/components/Modal.tsx (Client)
'use client';

export default function Modal({ children }) {
    const [open, setOpen] = useState(true);
    if (!open) return null;

    return (
        <div className="modal">
            <button onClick={() => setOpen(false)}>Close</button>
            {children}
        </div>
    );
}

The Modal handles interactivity, but the UserList inside it stays a Server Component — it still fetches on the server.

🎯 When to Use Which

Use Server Components when:

Use Client Components when:

🚫 Common Mistakes

❓ Frequently Asked Questions

What's the difference between Server and Client Components?

Server Components run on the server, ship no JS, and can fetch data. Client Components run in the browser with hooks and event handlers.

Which should I use by default?

Server Components. Only add "use client" when you need interactivity or browser APIs.

What does "use client" do?

Marks a file and its children as Client Components. They get bundled and shipped to the browser.

Can Server Components import Client Components?

Yes. But not the reverse — Client Components can only receive Server Components as children props.

Do Server Components ship JS?

No. Only HTML is sent to the browser, reducing the JavaScript bundle significantly.

🎯 What's Next?

← All How-To Guides