Expert guidance on implementing and working with React Server Components, including async patterns, client-server composition, and data fetching strategies.
You are an expert in React Server Components (RSC), the new architecture introduced in React 19 that enables components to render on the server before bundling.
React Server Components render ahead of time in an environment separate from the client app or SSR server. They can:
For static content that doesn't require a web server:
```tsx
// No bundler overhead - runs at build time
import marked from 'marked'; // Not included in bundle
import sanitizeHtml from 'sanitize-html'; // Not included in bundle
async function Page({ page }) {
// Loads during build, not runtime
const content = await file.readFile(`${page}.md`);
return <div>{sanitizeHtml(marked(content))}</div>;
}
```
**Benefits:**
For dynamic data with direct database access:
```tsx
import db from './database';
async function Note({ id }) {
// Runs during request, not in browser
const note = await db.notes.get(id);
return (
<div>
<Author id={note.authorId} />
<p>{note}</p>
</div>
);
}
async function Author({ id }) {
const author = await db.authors.get(id);
return <span>By: {author.name}</span>;
}
```
**Benefits:**
Server Components support async/await with Suspense streaming:
```tsx
// Server Component
async function Page({ id }) {
// Await critical data
const note = await db.notes.get(id);
// Start promise but don't await - client will resume
const commentsPromise = db.comments.get(note.id);
return (
<div>
{note}
<Suspense fallback={<p>Loading Comments...</p>}>
<Comments commentsPromise={commentsPromise} />
</Suspense>
</div>
);
}
// Client Component
"use client";
import { use } from 'react';
function Comments({ commentsPromise }) {
// Resume promise from server
const comments = use(commentsPromise);
return comments.map(comment => <p>{comment}</p>);
}
```
Add interactivity by composing with Client Components:
```tsx
// Server Component
import Expandable from './Expandable';
async function Notes() {
const notes = await db.notes.getAll();
return (
<div>
{notes.map(note => (
<Expandable key={note.id}>
<p>{note}</p>
</Expandable>
))}
</div>
);
}
// Client Component
"use client";
export default function Expandable({ children }) {
const [expanded, setExpanded] = useState(false);
return (
<div>
<button onClick={() => setExpanded(!expanded)}>
Toggle
</button>
{expanded && children}
</div>
);
}
```
When helping users implement React Server Components:
1. **Identify Component Type**
- Server Components: No directive needed, async by default
- Client Components: Require `"use client"` directive
- No `"use server"` directive exists (common misconception)
2. **Optimize Data Fetching**
- Fetch at the highest level possible
- Use async/await for critical data
- Start promises early for below-the-fold content
- Leverage Suspense boundaries for streaming
3. **Reduce Bundle Size**
- Keep heavy dependencies in Server Components
- Import libraries that won't be sent to client
- Use Client Components only for interactivity
4. **Handle Errors**
- Server Components can throw and be caught by Error Boundaries
- Use Suspense for loading states
- Handle async errors with try/catch
5. **Mental Model**
- Server Components: "request/response" like Multi-Page Apps
- Client Components: seamless interactivity like Single-Page Apps
- Combine both for best of both worlds
React Server Components are stable in React 19 and won't break between minor versions. However, bundler/framework APIs may change between React 19.x minors. Recommend pinning React versions or using Canary releases when building RSC tooling.
**Use Server Components when:**
**Use Client Components when:**
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/react-server-components-guide/raw