skip to content

In a React Server Components app, a file that starts with 'use client' imports a Button from another file that has no directive. Is that Button a client component, does its own file need a 'use client' line, and where in a file must the directive be written?

level: juniorimportance: must knowfreq 62%

answer

  1. one directive covers a subtree
  2. travels down imports, never up
  3. first statement, above the imports
  4. misplaced directive fails silently
  5. one module, one side of the line

basics

~20 s

Yes, the Button is a client component. Files below a client boundary inherit it through imports and need no directive of their own. The directive must be the first statement of a file, above every import.

solid answer

~50 s

The Button is client code. `'use client'` marks the module it appears in as the entry point of a client subgraph, and everything that module imports — the Button's file, and whatever the Button's file imports in turn — is pulled into the client bundle with it. So you do not repeat the directive on every file; you write it once, at the top edge of the interactive part of the tree. Adding it again lower down is harmless but pointless noise. On placement: the directive has to be the **first statement in the module**, above all `import` lines, with only comments allowed before it. If it sits below an import it is parsed as a plain string expression and does nothing — the file quietly stays a server module, and the failure shows up later as a hook or event handler that does not work.

go deeper

for a junior

Recall the two facts: the directive goes on the first line of the file, above the imports, and files imported below it are already client code. Say that server components are the default and carry no directive.

for a middle

Explain that the marker is per-module and flows down import edges only, and describe the silent failure mode of a misplaced directive — the file stays a server module and the error surfaces at a hook or handler instead.

for a senior

Show judgment about where the single directive belongs: at the top edge of the genuinely interactive part, not sprinkled defensively across files. Be ready to spot the one-file-two-jobs case and say the fix is to split the module.

for a principal

Own it as a reviewable rule: directives belong on leaf interactive modules, shared utility and barrel modules carry none, and adding one to a widely imported file is a change with a bundle-size consequence that needs justification.

## The short answer One directive covers a subtree. The Button is a client component because of *where it sits in the import graph*, not because of anything written in its own file. ## How the inheritance works An RSC app is one module graph, and by default every module in it is a server module. `'use client'` marks a single module as a doorway into the client. Once you are through that doorway, you stay through it: every module reachable from the marked one by `import` is compiled into the client bundle. ```js // Panel.jsx 'use client'; import { Button } from './Button'; // Button.jsx becomes client code import { formatDate } from './date'; // so does date.js ``` `Button.jsx` and `date.js` need no directive. The bundler already knows they are on the client side of the line because it walked there from a marked module. This is why writing `'use client'` at the top of every component file is a code smell rather than a safety measure. It is redundant inside an existing client subtree, and if someone later moves the file, the stray directive can quietly convert a subtree that should have stayed on the server. ## Which direction it travels Downward only, along imports. - A client module's imports become client code. **Yes.** - A server module that imports and renders a client component becomes client code. **No** — the parent stays a server component and still ships no JavaScript of its own. Server-imports-client is the normal direction. The reverse — a client module importing a server component — is what you cannot do, because the import would drag that component into the client graph, where it can no longer be a server component. ## Placement rules, precisely A directive is a string-literal statement at the head of a module. To be recognised, `'use client'` must be: - the **first statement** of the file — above every `import`, every `const`, every type declaration that emits code; - a plain string literal, single or double quotes, its own statement, terminated normally. Only comments may come before it: ```js // SPDX-License-Identifier: MIT 'use client'; import { useState } from 'react'; ``` Get this wrong and nothing shouts. Put it after an import and JavaScript sees an expression statement whose value is a discarded string; the module is treated as a server module. The symptom arrives at a distance — `useState` reported as unsupported, an `onClick` that never fires, or a mysterious "only server components can be async" style error somewhere near the file. ## The corollary: one file, one side Because the marker is per-module, a file cannot be half server and half client. If one file holds an interactive widget and a heavy server-only data helper, adding the directive drags the helper into the browser; omitting it breaks the widget. The fix is mechanical: split the file so the interactive part lives in its own module and carries the directive alone. ## What to say in the room Three sentences cover it: the directive marks a module, its effect flows down through imports so nested files inherit it, and it has to be the first statement in the file. If you add one more, make it the direction rule — a server parent rendering a client child stays a server component.

  • Is there any harm in adding 'use client' to every component file, just to be safe?
    Inside an existing client subtree it is redundant noise. The real harm is elsewhere: a stray directive on a file that could have stayed a server module — or on a shared file both sides import — turns a server subtree into shipped JavaScript. It also hides where the real boundary is, which is the thing reviewers need to see.
  • A file exports both an interactive widget and a server-side data helper. How do you mark it?
    You do not — you split it. The directive is per-module, so marking the file drags the helper into the client bundle and leaving it unmarked breaks the widget. Move the widget into its own module, put the directive there, and let the helper stay a server module.
  • What error do you typically see when the directive was written below the imports?
    Not a directive error. The file stays a server module, so you get the downstream complaint instead — a hook reported as unsupported in a server component, or an event handler prop rejected as non-serializable. Checking that the directive really is line one is the first thing to do when a client component behaves like a server one.

saying these in an interview costs you the question

  • Says every file in a client subtree needs its own directive
  • Thinks a nested file stays a server component unless marked
  • Places the directive under the imports
  • Believes rendering a client child makes the parent a client component
  • Assumes a misplaced directive raises a build error

context