-
Notifications
You must be signed in to change notification settings - Fork 27
RSC Compatibility
Decision: All Astryx components that use React hooks must include the 'use client' directive.
For related decisions, see:
- Component Authoring Guide — Full authoring conventions
- Distribution — Packages, versioning, and how Astryx ships
- RSC Utilities — Future server component integration patterns
Astryx components use useContext to consume theme tokens at runtime (via ThemeContext). This means every themed component is inherently a client component in React Server Components (RSC) environments.
Without the 'use client' directive, consumers who import any Astryx component in a Server Component file get a confusing createContext / useState error. The fix isn't obvious — they have to trace the import graph to understand why their file needs to be a client component.
This friction was reported by a dogfooder: a schema file that imported Text and Badge for rendering got pulled into a Server Component via page.tsx, and the error pointed at createContext deep in Astryx internals.
Every file in packages/core/src/ that uses any React hook must have 'use client' as its first statement (after any leading comments).
Hooks that trigger this requirement:
-
useState,useEffect,useRef,useContext,useCallback,useMemo -
useId,useReducer,useLayoutEffect,useTransition,useImperativeHandle -
createContext(creates a context that requires client-side resolution)
Files that do NOT need the directive:
- Pure re-export barrels (
index.ts) - Type-only files
- Utility functions with no hooks
- Static components that use only
forwardRef(no hooks) - StyleX style definitions (
*.stylex.ts)
The directive goes after any file-level JSDoc comment, before imports:
/**
* @file Button.tsx
* ...
*/
'use client';
import {forwardRef, useContext} from 'react';This matches the approach used by every major React design system:
| Library | Approach |
|---|---|
| Chakra UI | All components are client components. 'use client' baked into the package. |
| MUI | Runtime theme via context + Emotion. Everything is client. |
| Radix | Client components for interactive primitives. |
| shadcn/ui |
rsc: true config flag adds 'use client' to generated components. |
No major design system has solved server-renderable themed components yet.
The pre-compiled CSS work (Distribution) could change this. If themes resolve at build time via CSS layers instead of runtime context, then:
- Components like
Text,Badge,Dividerbecome genuinely server-renderable - Only interactive components (Dialog, DropdownMenu, etc.) would need
'use client' - Removing
'use client'from a component is a non-breaking change (it expands where the component can be used)
Until then, the directive stays on everything that uses hooks.
New components should include 'use client' from the start if they use any hooks. The Component Authoring Guide template includes it.
Rule of thumb: If your component file imports anything from
'react'other than types andforwardRef, it needs'use client'.