Day 5 — Client Components Done Right
30 Days Excerpt from 6+ Years Experience
🌗 Context & Continuity
Previous Day: Server Components Mastery
Today’s Focus: Client Components Done Right
Coming Up Tomorrow: Hydration, Streaming & Suspense Boundaries
Yesterday, we dismantled one of the biggest mental shifts in modern Next.js: Server Components are the default, not the exception. We explored how rendering on the server changes performance, security, and architectural decisions.
Today builds directly on that foundation.
If Server Components are where your app should live, then Client Components are where interactivity earns its place. Understanding when, why, and how to use Client Components correctly is one of the clearest signals that separates junior engineers from senior ones in Next.js.
This is not about memorizing "use client".
This is about owning the boundary between logic and interactivity.
🧭 Introduction
A common mistake many developers make when learning App Router is swinging from one extreme to another:
- First, everything becomes a Client Component because it “just works”.
- Then, everything becomes a Server Component because it’s “the default”.
Senior engineers don’t live in extremes.
They understand tradeoffs, cost, and intent.
Today, we’ll demystify Client Components — not as a fallback, but as a precision tool. By the end of this article, you’ll understand:
- What Client Components actually are
- Why they exist in a Server Components world
- How to design clean, performant boundaries
- Why misuse silently degrades performance
This knowledge is foundational to becoming a confident Next.js engineer in production environments.
🧩 Core Concept Deep Dive
What Is a Client Component — Really?
A Client Component is a React component that:
- Executes in the browser
- Has access to browser-only APIs
- Can use state, effects, and event handlers
- Is bundled and shipped to the client
In Next.js App Router, Client Components opt into the traditional React runtime.
That opt-in is explicit.
When you write:
"use client"
You are telling Next.js:
“This file and everything it imports must run in the browser.”
This single directive triggers a cascade of consequences.
Why Client Components Exist at All
If Server Components are faster, safer, and cheaper — why not use them everywhere?
Because users interact with applications, not HTML.
Client Components are required for:
- Click handlers
- Form state
- Modals and drawers
- Animations
- Browser APIs like
localStorage - Effects tied to lifecycle
- Real-time updates
In other words: interactivity lives on the client.
The mistake is not using Client Components.
The mistake is overusing them.
The Hidden Cost of "use client"
When a component becomes a Client Component:
- Its JavaScript must be sent to the browser
- Its dependencies become part of the client bundle
- It participates in hydration
- It increases memory usage
- It affects time-to-interactive
Senior engineers treat "use client" like a performance budget decision, not a convenience switch.
🧠 Practical Breakdowns & Real-World Thinking
The Boundary Principle
A powerful mental model is this:
Keep Client Components as small and as close to the leaf nodes as possible.
Beginners often wrap entire pages in Client Components just to handle a button click.
Senior engineers ask a different question:
“What is the smallest possible surface area that truly needs to be interactive?”
The answer is rarely the whole page.
Composition Over Conversion
Instead of turning a page into a Client Component, experienced developers:
- Keep the page and layout as Server Components
- Extract only the interactive part
- Pass data down as props
- Let the client handle interaction only
This preserves all the benefits of server rendering while enabling rich UI behavior.
Common Junior Mistake
A frequent JJC pattern looks like this:
- Needs a
useState - Adds
"use client"at the top - Imports everything into that file
- Accidentally ships half the app to the browser
This works — but at a silent cost.
Get devFemzy’s stories in your inbox
Join Medium for free to get updates from this writer.
A senior engineer sees this as architectural leakage.
How Seniors Think Differently
Senior engineers ask:
- Does this interaction truly require client state?
- Can this be a server action instead?
- Can I isolate the interactive concern?
- What happens to bundle size if this grows?
Client Components are not avoided — they’re scoped.
🧠 Advanced Insights You Rarely Hear Early
Client Components Infect Downward
Once a file is marked as a Client Component:
- All of its imports become client-side
- You cannot import Server Components into it
- You lose access to server-only features
This is why Client Components should usually sit at the edges, not the roots.
Client Components Are Not “Bad”
There’s a false narrative that Client Components are inferior.
That’s incorrect.
They are expensive, not wrong.
Used intentionally, they are essential for:
- Design systems
- Interaction layers
- UI primitives
- Controlled inputs
- Visual transitions
The skill is knowing where they belong.
Architectural Best Practice
A healthy Next.js app often looks like this:
- Server Components for data, layout, and structure
- Client Components for:
- Buttons
- Forms
- Toggles
- Interactive widgets
This separation scales beautifully as teams grow.
🪜 Step-by-Step Understanding
Let’s walk through the thought process — not code.
- Start with a Server Component by default
- Identify what requires user interaction
- Extract that logic into a small Client Component
- Pass data down from the server
- Keep the client focused on behavior, not data fetching
This workflow leads to cleaner, faster, and more maintainable applications.
The key is intention.
⚠️ Common Pitfalls (And Why They Happen)
- Turning entire pages into Client Components
Happens because it feels easier. Fix it by isolating interaction. - Fetching data inside Client Components unnecessarily
Happens due to old habits from CSR-only apps. - Overusing effects for things the server can handle
Happens when lifecycle thinking replaces architecture thinking. - Ignoring bundle impact
Happens because performance issues appear gradually, not immediately.
Each of these mistakes compounds as your app grows.
🧪 Mini-Reflection — What You Learned Today
Today unlocked a crucial mindset shift:
Client Components are not the default.
They are a deliberate opt-in for interactivity.
You now understand:
- What
"use client"really means - Why Client Components must be scoped carefully
- How senior engineers design component boundaries
- Why performance is architectural, not accidental
This is a major step toward writing production-grade Next.js.
🌉 Smooth Transition to Tomorrow
Today was about where interactivity lives.
Tomorrow, we’ll explore what happens when server-rendered HTML meets client-side JavaScript.
Hydration, streaming, and Suspense boundaries define:
- How fast your app feels
- How resilient it is under load
- How users experience transitions
Understanding Client Components sets the stage perfectly for understanding hydration behavior and streaming architecture.
✨ Share Your Progress
If you’re following along, tweet your setup screenshot or your progress with:
#30DaysOfNextJSand tag me @devFemzy on Twitter, I’ll retweet some of your posts!
This is Day 3, Keep going!
See you tomorrow.









