How the 'use client' Directive Works

The 'use client' directive marks a module and its dependencies as client code, creating the boundary between server and browser in a React Server Components app.

7 min read

The 'use client' directive marks a module and everything it imports as client code. When a Server Component imports that module, the bundler treats the import as the boundary between server-run and client-run code. Only the client side of that boundary is downloaded and executed in the browser.

Framework support required

The directive only means something in a React Server Components app built by a compatible framework or bundler, such as the Next.js App Router. In a plain client-only Vite app, every module already runs on the client and the directive has no effect.

What the directive marks

The directive applies to the whole module subtree, not just the file it sits in. If a file marked with 'use client' imports helper modules, those helpers become client code too, whether or not they carry their own directive.

App.jsxApp.jsx
'use client';
 
import { useState } from "react";
import { formatDate } from "./formatters";
import Button from "./Button";
 
export default function RichTextEditor({ timestamp, text }) {
  const date = formatDate(timestamp);
  const [draft, setDraft] = useState(text);
  return (
    <div>
      <p>{date}</p>
      <textarea value={draft} onChange={(e) => setDraft(e.target.value)} />
      <Button />
    </div>
  );
}

RichTextEditor is a Client Component, and so are formatters and Button, because the directive marks the entire dependency subtree. Their source is bundled and sent to the browser.

The boundary is in the module tree

The directive draws the boundary on the module dependency tree, not on the render tree. A child component that appears inside a Client Component can still be a Server Component if its module is never imported by client code.

Server to client handoff at a use client boundary

The server renders the tree until it reaches a client module, then stops evaluating that subtree. It sends the output so far, and the client finishes rendering the marked subtree once its code arrives. This is why a component can be server-rendered for one usage and client-rendered for another: the module tree decides each time.

When to add the directive

Add 'use client' only when a module needs the browser. Server Components stay the default.

  • Interactivity. Event handlers like onClick and state Hooks like useState only work in client code.
  • Browser APIs. DOM access, localStorage, canvas, and media APIs do not exist on the server.
  • Third-party libraries. Components that use createContext, most Hooks, or DOM APIs must run on the client.

If a library already ships compatible client markers, you can import it from a Server Component directly. If not, wrap it in a small client module of your own.

What can cross the boundary

Props passed from a Server Component into a Client Component must be serializable.

  • Allowed: primitives, arrays, plain objects, Date values, JSX, Promises, and Server Functions.
  • Not allowed: plain functions, classes, class instances, and unregistered symbols.

A plain event handler cannot cross the boundary, so it must be defined inside the client module. A Server Function can cross it, which is how a Client Component calls back into server code.

Common mistakes

The most common mistake is assuming the directive is about the render tree. A Client Component does not automatically make its children Client Components. The other common mistake is treating 'use client' as a React feature that works without a framework, when it only takes effect through a compatible bundler.

See Server Components vs Client Components for the full split, and React Server Functions and Server Actions for the server code that can cross the boundary the other way.

Rune AI

Rune AI

Key Insights

  • use client marks a module and its dependencies as client code.
  • The boundary lives on the module tree, not the render tree.
  • It must be the first line, above imports.
  • Add it for state, event handlers, or browser APIs.
  • Props crossing the boundary must be serializable.
RunePowered by Rune AI

Frequently Asked Questions

Does 'use client' have to be the first line of the file?

Yes. It must be at the very beginning, above any imports or code. Comments above it are allowed, and it must use single or double quotes, never backticks.

Can a file with no directive still run on the client?

Yes. If a client module imports it, the module becomes part of the client subtree and runs in the browser even without its own directive.

Conclusion

The use client directive marks a module and all of its dependencies as client code. It creates the server to client boundary on the module tree, so add it only where the browser is required.