Skip to main content

Overview

React Server Components (RSC) are a new type of component that runs only on the server. They allow you to build components that fetch data, access backend resources, and render to HTML without sending JavaScript to the client.
React Server Components are a framework feature. They require a framework like Next.js (App Router), or a custom setup with a bundler that supports RSC. They cannot be used in standalone React applications.

Server vs Client Components

Server Components

  • Run only on the server
  • Can access backend resources directly
  • Don’t increase client bundle size
  • Can’t use browser APIs or state
  • Can’t use hooks like useState, useEffect
  • Can be async functions

Client Components

  • Run on both server (SSR) and client
  • Can use all React features
  • Include hooks and interactivity
  • Increase bundle size
  • Marked with 'use client' directive

Server Component API

From packages/react/src/ReactServer.js:43:
Server components have a limited API compared to client components. Notable exclusions:
  • No useState, useReducer
  • No useEffect, useLayoutEffect
  • No useContext (use props instead)
  • No useTransition, useDeferredValue

Basic Server Component

Client Component

Composing Server and Client Components

Server Component Using Client Component

Passing Server Components as Children

Data Fetching

Direct Database Access

API Calls

React Cache

From packages/react/src/ReactCacheServer.js, use cache to deduplicate requests:

Streaming with Suspense

Server components work seamlessly with Suspense for streaming:

Server Actions

Server components can use server actions for mutations:

Error Handling

Serialization Limits

Server components can only pass serializable props to client components:Allowed:
  • Primitives (string, number, boolean, null)
  • Arrays and plain objects
  • Date objects
  • React elements
Not Allowed:
  • Functions
  • Class instances
  • Symbols
  • Promises (directly)

Benefits

  1. Reduced Bundle Size: Server component code never goes to the client
  2. Direct Backend Access: Query databases, read files, use server-only APIs
  3. Improved Performance: Less JavaScript to download and parse
  4. Automatic Code Splitting: Each server component is a natural split point
  5. Better Security: Keep sensitive code and credentials on the server

Best Practices

  1. Use server components by default: Only add 'use client' when needed
  2. Push client boundaries down: Keep client components as deep in the tree as possible
  3. Pass server components as children: Compose server and client components effectively
  4. Cache expensive operations: Use React cache for request deduplication
  5. Use Suspense for streaming: Stream expensive components independently
  6. Handle errors properly: Use error boundaries with server components
  7. Avoid prop serialization: Don’t pass complex objects to client components

Limitations

  1. No hooks (except allowed ones): Can’t use useState, useEffect, etc.
  2. No browser APIs: window, document, etc. are not available
  3. No event handlers: onClick, onChange, etc. require client components
  4. No Context: Can’t use React Context (use props or composition)
  5. Framework dependency: Requires a supporting framework

When to Use Client Components

Use 'use client' when you need:
  • Interactivity (onClick, onChange, etc.)
  • State management (useState, useReducer)
  • Effects (useEffect, useLayoutEffect)
  • Browser APIs (localStorage, WebSocket, etc.)
  • Context (useContext)
  • Lifecycle methods

Server Component Hooks

Allowed hooks in server components:
  • useId: Generate unique IDs
  • useCallback: Memoize callbacks
  • useMemo: Memoize values
  • useDebugValue: Add debug labels
  • cache: Cache function results

See Also

  • Suspense - Streaming and loading states