🎯

react-use-client-boundary

🎯Skill

from flpbalada/my-opencode-config

VibeIndex|
What it does

Guides developers in correctly applying the "use client" directive in React/Next.js, helping manage server and client component boundaries.

πŸ“¦

Part of

flpbalada/my-opencode-config(40 items)

react-use-client-boundary

Installation

πŸ“‹ No install commands found in docs. Showing default command. Check GitHub for actual instructions.
Quick InstallInstall with npx
npx skills add flpbalada/my-opencode-config --skill react-use-client-boundary
1Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Overview

# React "use client" Directive & Client Boundaries

Understanding when to use (and when NOT to use) the "use client" directive in React Server Components architecture.

Core Concept: The Boundary

"use client" marks a boundary between server and client components - not a label for individual components.

Critical Rule: Once inside a client boundary, ALL imported components are automatically client components. You should NOT add "use client" to child components that are already imported by a parent client component.

Mental Model: The Fence

Think of "use client" as a fence or gate:

```

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”

β”‚ SERVER TERRITORY β”‚

β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚

β”‚ β”‚ page.tsx β”‚ (Server Component - default) β”‚

β”‚ β”‚ β”‚ β”‚

β”‚ β”‚

│───────────────────────┐ β”‚

β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚

β”‚ β–Ό β”‚

β”‚ ════════════════ "use client" FENCE ════════════ β”‚

β”‚ β”‚ β”‚

β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚

β”‚ β”‚ CLIENT TERRITORY β–Ό β”‚ β”‚

β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚

β”‚ β”‚ β”‚ Header.tsx │───▢│ NavMenu.tsx β”‚ β”‚ β”‚

β”‚ β”‚ β”‚"use client" β”‚ β”‚ (no directiveβ”‚ β”‚ β”‚

β”‚ β”‚ β”‚ β”‚ β”‚ needed!) β”‚ β”‚ β”‚

β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚

β”‚ β”‚ β”‚ β”‚

β”‚ β”‚ You're already inside - no more fences needed β”‚ β”‚

β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚

β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

```

When to Use "use client"

Add the directive when ALL of these are true:

  1. The component is imported by a Server Component (directly or as a page entry)
  2. AND the component needs client-side features:

- React hooks (useState, useEffect, useContext, etc.)

- Event handlers (onClick, onChange, onSubmit, etc.)

- Browser APIs (window, document, localStorage, etc.)

- Third-party libraries that use any of the above

When NOT to Use "use client"

  1. Already inside a client boundary - parent component has "use client"
  2. Component is pure presentation - just renders props, no interactivity
  3. "Just to be safe" - this creates confusion and unnecessary boundaries
  4. Every component that uses props - props work fine in server components

Common Mistake: Redundant Directives

```tsx

// ❌ WRONG: Unnecessary "use client" in child

// components/form.tsx

"use client"

import { Input } from "./input"

import { Button } from "./button"

export function Form() {

const [value, setValue] = useState("")

return (

)

}

// components/input.tsx

"use client" // ❌ WRONG - already a client component!

export function Input({ value, onChange }) {

return onChange(e.target.value)} />

}

// components/button.tsx

"use client" // ❌ WRONG - already a client component!

export function Button({ children, type }) {

return

}

```

Correct Approach: Single Boundary

```tsx

// βœ… CORRECT: Only the entry point has "use client"

// components/form.tsx

"use client"

import { Input } from "./input"

import { Button } from "./button"

export function Form() {

const [value, setValue] = useState("")

return (

)

}

// components/input.tsx

// βœ… No directive - imported by client component

export function Input({ value, onChange }) {

return onChange(e.target.value)} />

}

// components/button.tsx

// βœ… No directive - imported by client component

export function Button({ children, type }) {

return

}

```

Decision Flowchart

```

Is this component imported by a Server Component?

β”‚

β”œβ”€ NO ──▢ Is its parent/importer a Client Component?

β”‚ β”‚

β”‚ β”œβ”€ YES ──▢ ❌ Don't add "use client" (already in boundary)

β”‚ β”‚

β”‚ └─ NO ───▢ Check the import chain upward

β”‚

└─ YES ─▢ Does this component need client features?

β”‚

β”œβ”€ NO ──▢ ❌ Don't add "use client" (keep it server)

β”‚

└─ YES ─▢ βœ… Add "use client" (create boundary here)

```

Real-World Example: Page with Interactive Section

```tsx

// app/products/page.tsx (Server Component - no directive)

import { ProductList } from "@/components/product-list"

import { SearchFilters } from "@/components/search-filters"

import { getProducts } from "@/lib/api"

export default async function ProductsPage() {

const products = await getProducts() // Server-side data fetching

return (

Products

{/ Client boundary starts here /}

{/ Server component /}

)

}

// components/search-filters.tsx

"use client" // βœ… Boundary: imported by server, needs state

import { FilterDropdown } from "./filter-dropdown"

import { PriceSlider } from "./price-slider"

export function SearchFilters() {

const [filters, setFilters] = useState({})

return (

{/ No directive needed /}

{/ No directive needed /}

)

}

// components/filter-dropdown.tsx

// βœ… No "use client" - already inside client boundary

export function FilterDropdown({ onSelect }) {

return

}

// components/price-slider.tsx

// βœ… No "use client" - already inside client boundary

export function PriceSlider({ onChange }) {

return onChange(e.target.value)} />

}

```

Edge Case: Shared Components

When a component is used by BOTH server and client components:

```tsx

// components/card.tsx

// No directive - works in both contexts if it's pure presentation

export function Card({ title, children }) {

return (

{title}

{children}

)

}

// app/page.tsx (Server Component)

import { Card } from "@/components/card"

// Card renders as server component here

// components/modal.tsx

"use client"

import { Card } from "@/components/card"

// Card renders as client component here (inside boundary)

```

Troubleshooting Common Errors

Error: "useState only works in Client Components"

Cause: Using hooks in a component without "use client" that's imported by a server component.

Fix: Add "use client" to the component using the hook, OR move the hook usage to a parent client component.

Error: "Event handlers cannot be passed to Client Components from Server Components"

Cause: Trying to pass a function from server to client component.

Fix: Move the event handler logic to the client component, or restructure the boundary.

Error: "async/await is not yet supported in Client Components"

Cause: Using async component syntax inside a client boundary.

Fix: Keep data fetching in server components, pass data as props to client components.

Best Practices Summary

| Do | Don't |

|---|---|

| Place "use client" at the highest necessary point | Sprinkle "use client" on every component |

| Keep the client boundary as small as possible | Make entire pages client components |

| Let child components inherit client context | Add redundant "use client" to children |

| Use server components for data fetching | Fetch data in client components when avoidable |

References

  • [React Docs: "use client"](https://react.dev/reference/rsc/use-client)
  • [Next.js Discussion: Client Component Boundaries](https://github.com/vercel/next.js/discussions/46795)

More from this repository10

🎯
five-whys🎯Skill

Systematically uncovers root causes of problems through iterative questioning, revealing underlying issues beyond surface-level symptoms.

🎯
social-proof-psychology🎯Skill

Optimizes user trust and conversion by strategically displaying social validation through testimonials, user stats, and expert endorsements.

🎯
cognitive-fluency-psychology🎯Skill

Enhances user comprehension and engagement by applying cognitive fluency principles to simplify information processing across content and interfaces.

🎯
hooked-model🎯Skill

Designs habit-forming products by mapping user triggers, actions, rewards, and investments to create engaging, addictive product experiences.

🎯
cognitive-biases🎯Skill

Applies cognitive bias insights to optimize product design, user experiences, and decision-making strategies by leveraging psychological principles.

🎯
typescript-satisfies-operator🎯Skill

Validates TypeScript object types while preserving precise literal types, preventing type widening and catching type-related errors early.

🎯
typescript-best-practices🎯Skill

Enforces TypeScript best practices and coding standards through comprehensive linting and configuration rules for consistent, high-quality code.

🎯
status-quo-bias🎯Skill

Helps design product changes and migrations by understanding users' psychological resistance to change and creating strategies to overcome status quo bias.

🎯
kanban🎯Skill

Visualize and optimize team workflow by creating Kanban boards that track tasks, limit work-in-progress, and improve delivery efficiency.

🎯
theme-epic-story🎯Skill

I apologize, but I cannot generate a description without seeing the actual content or context of the "theme-epic-story" skill from the repository. Could you provide more details about what this spe...