The `use client` Directive
The `use client` directive marks a module as a Client Component entry point and establishes a boundary between client-side and server-side module graphs. In frameworks that support React Server Components, it enables browser-only features such as state, effects, and event handlers in that component subtree.
`use client` is a directive written at the top of a module, before other statements. In a React Server Components environment such as Next.js App Router, it tells the framework that the module is an entry point for Client Components rather than a Server Component.
The directive creates a module-graph boundary: modules imported by a Client Component entry point are treated as part of the client-side graph unless another framework rule changes that behavior. This means the boundary should be placed where client-only behavior actually begins, rather than added to every component that happens to render on the page.
Client Components are appropriate when code needs browser interaction, such as `useState`, `useEffect`, event handlers, or browser APIs. Server Components can instead perform server-side work and keep server-only dependencies and implementation details out of the browser bundle.
A Client Component can receive data from a Server Component, but values crossing the Server Component/Client Component boundary generally need to be serializable according to the framework's supported rules. Functions defined on the server cannot ordinarily be passed as ordinary component props to a Client Component.
The directive does not mean that every piece of code in the application runs only in the browser. It identifies a client entry point and affects how the framework builds and renders the associated module graph; the exact rendering behavior depends on the framework and its React Server Components implementation.
Key points
- `use client` defines a Client Component entry point.
- It establishes a server/client module boundary.
- Client Components support interactive features such as state, effects, and event handlers.
- Use it at the smallest appropriate boundary rather than marking an entire application client-side.
- Props crossing the boundary generally must satisfy the framework's supported serialization constraints.
Interview questions
What does `use client` do?
It marks a module as a Client Component entry point in a React Server Components environment. The framework uses that marker to establish a boundary between server and client module graphs. It allows the component to use client-side features such as state, effects, and event handlers. It should be added where client interactivity is needed rather than indiscriminately across the application.
Why can't every React component use `useState` in a Server Component?
Server Components are designed to execute in the server-oriented React Server Components model and do not provide browser-side interactive state in the same way Client Components do. `useState` requires client-side component behavior, so the interactive portion must be placed behind a Client Component boundary. The `use client` directive establishes that boundary. A common design is to keep data fetching or static UI on the server and isolate interactive controls in a small Client Component.
What happens to imports below a `use client` boundary?
The directive identifies the module as a client entry point, and the framework builds the relevant dependency graph for client execution. Consequently, imported modules can become part of the client-side graph as well. This is why adding `use client` high in a component hierarchy can substantially increase the amount of code intended for the browser. A useful optimization is to place the boundary as close as practical to the interactive code.
How do Server Components pass data to Client Components?
A Server Component can render a Client Component and provide data through props. The values crossing that boundary must conform to the framework's supported serialization rules. Ordinary server-defined functions are not generally transferable as normal props, although frameworks can provide specific mechanisms such as Server Functions for supported cases. Keeping the data crossing the boundary small and well-defined helps preserve the benefits of server rendering and reduces client complexity.
How would you choose where to put a `use client` boundary in a large application?
I would first identify the smallest subtree that genuinely requires browser interactivity, such as state, effects, event handlers, or browser APIs. I would keep data fetching and server-only logic outside that boundary when practical, then pass the necessary data into the interactive component. I would also inspect the resulting client dependency graph because a boundary can pull imported modules into client-side processing. The goal is not simply to minimize the number of Client Components, but to keep the client surface intentional while preserving a clean component architecture.