Introduction
React Server Components (RSCs) are among the most significant updates introduced in modern React. They allow developers to run components on the server rather than in the browser, resulting in faster applications, smaller bundles, and better performance. If you are coming from older versions of React or traditional client-side rendering, the concept may feel new. This article explains RSC in simple, easy-to-understand words and also guides you step-by-step on how to migrate your existing application to the latest version of React.
What Are React Server Components?
React Server Components are components that run only on the server. They never ship JavaScript to the browser. Instead, the server sends lightweight HTML and serialized data to the client.
Key Features
Run on the server, not the browser.
Never included in the client-side JavaScript bundle.
Can securely access server-only resources (DB, files, API keys).
Reduce bundle size → faster load time.
Improve SEO automatically.
Designed for modern full-stack frameworks.
How React Server Components Work
RSC uses a hybrid rendering model:
Some components run on the server (Server Components).
Some run on the client (Client Components).
React decides how to combine them efficiently.
Server Component Example
// This file can be a server component by default
import db from "./db";
export default async function ProductList() {
const products = await db.getProducts();
return (
<ul>
{products.map(p => <li key={p.id}>{p.name}</li>)}
</ul>
);
}
Client Component Example
"use client";
export default function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
Runs in the browser
Needed for interactivity
Server vs Client Components: Quick Comparison
| Feature | Server Components | Client Components |
|---|
| Runs on | Server | Browser |
| JS bundle | No | Yes |
| Access DB | Yes | No |
| SEO | Excellent | Depends |
| Interactivity | No | Yes |
Benefits of React Server Components
1. Smaller JavaScript Bundle Size
Since server components do not ship JS to the client, bundle size is much smaller.
2. Better Performance
3. Direct Access to Server Resources
Server Components can:
4. Great SEO
Content is generated on the server → search engines can index easily.
5. Modern Full-Stack Support
Perfect for frameworks like:
Next.js 13+
Remix (future updates)
RSC-ready systems
How to Migrate to React Server Components
Migration steps depend on your project setup. Below is the simplest path for modern React applications.
Step 1: Upgrade to Latest React and ReactDOM
Ensure you are using:
React 18 or above
ReactDOM 18 or above
Install the latest versions:
npm install react@latest react-dom@latest
Step 2: Use a Framework That Supports RSC
React Server Components work best in:
Best option: Next.js
Install Next.js 13+:
npx create-next-app@latest myapp
Select App Router, which is fully RSC-ready.
Step 3: Convert Your Components to Server or Client
Server Components (default)
All components are server components unless you add:
"use client";
When to use server components
When to use client components
Step 4: Move Data Fetching to Server Components
Old React pattern:
useEffect(() => {
fetch('/api/products').then(...);
}, []);
Modern RSC pattern:
export default async function Products() {
const products = await fetch("https://api.example.com/products").then(r => r.json());
return <ProductList items={products} />;
}
No useEffect needed.
Step 5: Split Client Logic Into Client Components
Example:
"use client";
export default function AddToCart({ id }) {
return <button onClick={() => console.log("Added", id)}>Add to Cart</button>;
}
Use this inside a server component:
import AddToCart from "./AddToCart";
export default async function Product({ id }) {
const product = await db.getProduct(id);
return (
<div>
<h2>{product.name}</h2>
<AddToCart id={product.id} />
</div>
);
}
Step 6: Use Layout and Streaming for Faster Loading
Next.js + RSC supports React Suspense and streaming.
Example:
export default function Layout({ children }) {
return (
<html>
<body>{children}</body>
</html>
);
}
With Suspense:
<Suspense fallback={<p>Loading...</p>}>
<Products />
</Suspense>
Step 7: Clean Up Old Client-Side Patterns
Remove unnecessary:
useEffect for data fetching
JSON parsing logic in browser
Client-side state management for server data
Replace with server functions and direct rendering.
Common Migration Issues and Fixes
1. Error: “useState is not allowed in Server Components”
Add:
"use client";
2. Private environment variables not accessible
Server Components CAN access .env, but client components cannot.
3. API routes returning unnecessary JSON
You can now call databases directly inside RSC — no need for API proxy.
Example Folder Structure in Next.js 13+
app/
layout.js // server component
page.js // server component
products/
page.js // server
ProductCard.js // server
AddToCart.js // client
Best Practices for Migrating to RSC
Keep most components as server components.
Only use client components when necessary.
Offload heavy computation to server.
Use Suspense boundaries for streaming.
Avoid unnecessary client-side JavaScript.
Use server-side fetching instead of API calls.
Conclusion
React Server Components bring a major improvement to how React handles rendering, performance, and data fetching. By running components on the server and shipping less JavaScript to the client, you can build faster and more scalable applications. Migrating to RSC is straightforward once you upgrade to the latest React version and adopt best practices using modern frameworks like Next.js. With this new hybrid rendering model, React development becomes more powerful, secure, an