React Server Components Style
The boundary discipline for React Server Components, what runs on the server, what crosses the wire, and where
"use client"and"use server"belong. Framework-agnostic; the Next.js-specific routing and caching rules live in Next.js App Router Style.
In the RSC model, components are Server Components by default. They render on the server, can be async, fetch data directly, and read secrets or the filesystem, but they cannot use state, effects, event handlers, or browser APIs. Source: react.dev, https://react.dev/reference/rsc/server-components, 2026-05-31
"use client" marks a boundary, not a file flavor
"use client" at the top of a module marks the entry point into the client graph: that module and everything it imports ship to the browser. So put the directive at the leaves and keep it minimal. A component is not "a client component" because it is interactive in isolation, it is client because it sits behind a "use client" boundary. Source: react.dev RSC reference, 2026-05-31
Only serializable props cross the wire
Props passed from a Server Component to a Client Component must be serializable: plain objects, arrays, strings, numbers, and Server Functions, but not class instances, or arbitrary functions. To keep heavy work on the server, pass Server Components as children (or as props) into Client Components rather than importing them across the boundary:
// client island wraps server-rendered content it never imports
<ClientTabs>
<ServerHeavyChart />
</ClientTabs>
Source: react.dev RSC reference, 2026-05-31
"use server" is for Server Functions
"use server" marks Server Functions (Actions) callable from the client. Treat every Server Function as a public, untrusted endpoint: authenticate, authorize, and validate inputs with Zod exactly as you would an API route, because the client can invoke it directly. Never assume a Server Function is "internal." Source: react.dev RSC reference, 2026-05-31
Composition rules of thumb
- Keep client islands small and push them to the leaves; layouts and data loaders stay server-side.
- Fetch in Server Components or framework loaders, not in client effects (see React
no-fetch-in-effect). - Do not import server-only modules (db clients, secrets) into anything reachable from a
"use client"boundary; use aserver-onlyguard.
Boundary Contract
| Boundary | Default | Banned pattern | Proof |
|---|---|---|---|
| Server Component | Owns data loading, secrets, filesystem, and non-interactive composition | Passing raw provider objects to client leaves | Serialization check or rendered route |
| Client Component | Owns event handlers, browser APIs, local state, animation | Importing server-only modules behind "use client" |
Build failure or import audit |
| Server Function | Authenticates, authorizes, validates input, returns typed result | Treating "use server" as internal-only |
Action/API test |
| Composition | Pass server-rendered children into client shells | Importing heavy server content from client files | Bundle inspection or route render |
Proof
For RSC edits, prove the boundary from both sides: the server path can access its data without leaking secrets, and the client bundle contains only the island that needs interactivity. A route render plus import/bundle review is the minimum honest check for boundary changes.
Style Rule Contract
This page follows Style Rule Contract: name the default pattern, banned pattern, reason, exception, proof, and codification path clearly enough that the next agent can apply the rule without asking Kevin again. If a local repo has a stricter rule, follow the local rule and update the wiki when the decision becomes durable.
Timeline
- 2026-07-01 | Aligned this page with Style Rule Contract so style guidance names default behavior, banned patterns, exceptions, proof, and codification expectations. Source: User request, 2026-07-01
- 2026-07-01 | Added a Server Components boundary contract and proof rule for serialization, client islands, server functions, and bundle/import review. Source: User request, 2026-07-01
- 2026-05-31 | Page created from the react.dev Server Components reference and React 19 stable notes. Captured server-by-default semantics,
"use client"as a boundary, the serializable-props rule, children-as-server-content composition, and"use server"as an untrusted endpoint. Differentiated from the Next-specific Next.js App Router Style. Source: https://react.dev/reference/rsc/server-components, 2026-05-31