C.W.K.
Stream
Lesson 04 of 08 · published

The Decision Framework

~18 min · server vs client, decision, tree

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

The default is Server. Promote on hard requirement only.

Walk every component you write through this tree:

Does it need...
├── useState / useEffect / useReducer?  → Client
├── onClick / onChange / onSubmit?      → Client
├── Browser APIs (window, navigator)?   → Client
├── A library that requires hooks?      → Client
└── None of the above?                  → Server ✓

What "mostly server" looks like

In a typical Next.js app, 80–90% of components are Server Components. Pages, lists, cards, headers, footers, articles, tables — all server. Only the leaves that hold state or event handlers wear 'use client'.

Real examples

  • Blog post page (renders content) — Server.
  • Search bar (controlled input) — Client.
  • Markdown renderer (data shape) — Server.
  • Theme toggle (writes to localStorage) — Client.
  • Like button (optimistic UI) — Client wrapper, server data feed.

Code

Server: blog page just renders·tsx
// app/blog/[slug]/page.tsx — Server
export default async function BlogPost({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = await fetchPost(slug);
  return <article>{post.content}</article>;
}
Client: search bar reads/writes state·tsx
// components/SearchBar.tsx — Client
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';

export function SearchBar() {
  const [q, setQ] = useState('');
  const router = useRouter();
  return (
    <form onSubmit={(e) => { e.preventDefault(); router.push(`/search?q=${encodeURIComponent(q)}`); }}>
      <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search" />
    </form>
  );
}

External links

Exercise

Audit any 10 components in your codebase. For each, decide Server or Client by the framework above. Flip any that don't actually need 'use client'.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.