React  

From CSR to SSR to RSC: The Evolution of React Rendering

Introduction

React has come a long way since its launch in 2013. What started as a simple component-based library for building dynamic user interfaces has now evolved into a comprehensive framework capable of handling both frontend and backend logic. At the heart of this evolution lies a major shift in how rendering works in React.

From Client Side Rendering (CSR) to Server Side Rendering (SSR) and now to the groundbreaking React Server Components (RSC), each stage reflects a new way of thinking about performance, scalability, and user experience.

In this article, we'll explore these rendering paradigms like where we started, why we evolved, and how React Server Components are reshaping modern web development.

1. The Foundation: Client-Side Rendering (CSR)

Client-Side Rendering is how React was traditionally used in projects like Create React App.

What is CSR?

In CSR, the server sends a nearly empty HTML file to the browser, which then downloads and runs a large JavaScript bundle. Once loaded, React takes over and renders the UI inside the browser.

<!-- index.html -->
<html>
  <head>
    <title>React App</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="bundle.js"></script>
  </body>
</html>

Pros

  • Interactive SPA-like experience

  • Great for dynamic UIs and real-time updates

  • Developer-friendly (hot reload, hooks, dev tools)

Cons

  • Slow initial load on slow networks

  • No meaningful HTML for search engines- SEO issues

  • JavaScript heavy -: bad for low-power devices

CSR was a great start, but performance and SEO limitations pushed developers toward server-rendered solutions.

2. The Evolution: Server-Side Rendering (SSR)

What is SSR?

Server Side Rendering generates the HTML on the server at request time and sends it to the client. After that, React "hydrates" the HTML to make it interactive.

This is the model used by Next.js by default.

// pages/index.tsx in Next.js
export default function Home({ posts }) {
  return (
    <ul>
      {posts.map(post => <li key={post.id}>{post.title}</li>)}
    </ul>
  );
}

export async function getServerSideProps() {
  const posts = await fetchPosts();
  return { props: { posts } };
}

Pros

  • Faster First Contentful Paint (FCP)

  • Fully crawlable by search engines -: better SEO

  • Improves perceived performance

Cons

  • Requires hydration (React re-runs on client)

  • Can lead to duplicated logic (server render + client hydrate)

  • Increased server resource usage

SSR struck a balance between performance and interactivity, but it still shipped full JS bundles and had hydration costs.

3. Optimization Layer: SSG and ISR

Static Site Generation (SSG)

SSG generates pages at build time instead of at request time.

  • Great for blogs, marketing sites

  • Pages are cached on a CDN

  • No server cost per request

export async function getStaticProps() {
  const posts = await fetchPosts();
  return { props: { posts } };
}

Incremental Static Regeneration (ISR)

ISR introduced the ability to regenerate individual static pages in the background, blending static performance with dynamic content.

export async function getStaticProps() {
  return {
    props: await fetchData(),
    revalidate: 60 // Regenerate page every 60 seconds
  };
}

These optimizations helped reduce runtime costs but still required hydration and shipped full JS bundles.

4. The Breakthrough: React Server Components (RSC)

What are React Server Components?

React Server Components (RSC) introduce a new type of component that runs only on the server. These components never get shipped to the client , reducing JavaScript bundle size and hydration costs.

# First introduced in 2020, RSC became production-ready with Next.js 13/14 and React 18+.

Key Features

  • Only client components ship JavaScript

  • Built-in support for server-side data fetching

  • No useEffect or lifecycle hacks for async data

  • Can stream partial UI from server

Real Example

/app/products/page.tsx (Server Component)

// This runs ONLY on the server
export default async function ProductsPage() {
  const products = await getProductsFromDB();

  return (
    <ul>
      {products.map(p => (
        <li key={p.id}>{p.name}</li>
      ))}
    </ul>
  );
}

/components/LikeButton.tsx (Client Component

'use client';
import { useState } from 'react';

export function LikeButton() {
  const [likes, setLikes] = useState(0);
  return <button onClick={() => setLikes(likes + 1)}>👍 {likes}</button>;
}

5. Why This Matters: Performance, DevX, and UX

Performance Gains

  • Fewer JS bundles to parse and execute

  • Smaller page payloads

  • Faster interaction readiness with streaming

Better Developer Experience

  • Server-only logic kept on server

  • No manual client-side data fetching

  • Built-in error boundaries, Suspense, and loading states

Seamless Scalability

  • Fits well with edge functions, caching, and CDNs

  • Ideal for large apps with both dynamic and static content

React Server Components give developers the tools to create fast, scalable, and maintainable apps without sacrificing interactivity.

6. The Future: Edge + Streaming + AI?

The future of React isn’t purely on the client or the server; it’s hybrid.

With Edge rendering, streamed UI, and selective hydration, modern apps can:

  • Load instantly

  • Personalize at the edge 

  • Fetch data efficiently

  • Use AI and ML models server-side (e.g  RAG-based personalization)

Conclusion

React’s rendering journey from CSR to SSR to RSC mirrors the industry's growing emphasis on performance, SEO, scalability, and developer ergonomics.

  • CSR gave us rich interactivity but bloated performance.

  • SSR and SSG brought better SEO and initial loading.

  • RSC marks a foundational shift, allowing us to run logic where it belongs and send only what’s needed to the client.

With React Server Components, we are no longer just optimizing. We are redefining how modern web apps are built.