Third-Party Components in RSC

Most Libraries Need a "use client" Wrapper

Third-Party Components in RSC

Libraries that use React hooks must run on the client. Wrap them in a tiny `'use client'` module and re-export — that module is your boundary.

4 min read Level 2/5 #nextjs#third-party#client
What you'll learn
  • Wrap a hook-using library in a `'use client'` module
  • Re-export the components you need
  • Treat the wrapper file as the client boundary

Most React UI libraries use hooks like useState or useEffect internally. Importing them straight into a Server Component will fail at runtime. The fix is a one-line wrapper.

The Wrapper Pattern

// components/ui/client.ts
'use client'

export { Button } from 'some-ui-lib'
export { Dialog, DialogTrigger, DialogContent } from 'some-ui-lib'

Now any Server Component can safely import Button from ./components/ui/client. The re-export file is the client boundary; the library’s internals run on the client.

Why It Works

The 'use client' directive turns the file into a client module. Everything it exports is automatically a client component to its callers. You did not need to fork or rewrite the library — just give it a place to live on the client side of the divide.

Using the Wrapper

// app/page.tsx (server)
import { Button } from '@/components/ui/client'

export default function Page() {
  return (
    <main>
      <h1>Welcome</h1>
      <Button>Click me</Button>
    </main>
  )
}

The page itself stays a Server Component. Only Button ships to the browser.

Libraries That Already Ship Dual Exports

Some modern libraries (Radix UI primitives, etc.) already mark their files with 'use client' internally, so the wrapper step is unnecessary — you can import them directly. Check the library’s docs; if it errors with “You’re importing a component that needs useState”, that is your cue to add the wrapper.

Server Actions →