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.
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.