'use client' at the leaves

Mark only interactive leaves; fetch in an async server parent.

React docsreact.dev
Reference for the 'use client' directive: marks a component as a Client Component.
ReferenceView on react.dev ↗

From next-best-practices, rsc-boundaries.md and directives.md.

Where the boundary goes

Click a node to toggle 'use client', or pick a preset.

app/shop/page.tsx treeTree
    Result—
    JS shipped 0 KB
      // app/shop/page.tsx
      export default async function Page() {
        const products = await db.product.findMany()
        return <ProductList products={products} />
      }
      
      // add-to-cart-button.tsx
      'use client'
      import { useState } from 'react'
      
      export function AddToCartButton({ id }: { id: string }) {
        const [pending, setPending] = useState(false)
        return <button onClick={() => addToCart(id)}>Add</button>
      }

      Async client component linter

      Edit or toggle, then press Split it to fix.

      —
      Linterrsc-boundaries
        page.tsx
        // not created yet
        // page.tsx
        export default async function Page() {
          const user = await getUser()
          return <UserProfile user={user} />
        }
        
        // user-profile.tsx
        'use client'
        export function UserProfile({ user }: { user: User }) {
          return <div>{user.name}</div>
        }

        Server, Client, or split?

        Tick what one component needs.

        ComponentUses
        Capabilities

        Needs the browser

        Needs the server

        Either

        Verdict—

        Why it matters, pros and cons

        Why it matters

        'use client' ships the file and its imports. Only Server Components can await.

        Pros

        • Less JS in the browser.
        • Secrets and DB clients stay server-side.
        • Interactive parts stay small and findable.

        Cons

        • Props across the boundary must be serializable.
        • Very interactive screens are client at the top anyway.
        • Server children pass only as children, not imports.