← All articles
Frontend2 min read

Understanding React Server Components

A practical mental model for React Server Components — what runs where, why it matters, and how to avoid the most common pitfalls.

S

Swapnika Voora

Author

React Server Components (RSC) are one of the biggest shifts in the React programming model in years. Instead of shipping every component to the browser, you can render pieces of your UI on the server and stream the result to the client. The payoff is smaller bundles, faster loads, and direct access to your data layer.

The core mental model

Every component is a Server Component by default in the App Router. It only becomes a Client Component when you opt in with the "use client" directive.

app/page.tsx
// Server Component — runs on the server, never ships to the browser
import { db } from "@/lib/db"
import { LikeButton } from "./like-button"
 
export default async function Page() {
  const posts = await db.post.findMany() // direct DB access, no API route
 
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>
          {post.title}
          <LikeButton postId={post.id} />
        </li>
      ))}
    </ul>
  )
}

The LikeButton needs interactivity, so it lives in its own file:

app/like-button.tsx
"use client"
 
import { useState } from "react"
 
export function LikeButton({ postId }: { postId: string }) {
  const [liked, setLiked] = useState(false)
  return (
    <button onClick={() => setLiked((v) => !v)}>
      {liked ? "♥ Liked" : "♡ Like"}
    </button>
  )
}

What runs where?

Capability Server Component Client Component
async/await ⚠️ (via hooks)
Access to secrets
useState/useEffect
Adds to JS bundle

Common pitfalls

  1. Importing server-only code into a client component. Use the server-only package to fail fast at build time.
  2. Passing non-serializable props across the boundary. Functions and class instances can't cross from server to client.
  3. Marking everything "use client". You lose the benefits — push the boundary as far down the tree as you can.

Rule of thumb: keep components on the server unless they need state, effects, or browser-only APIs.

With this model in place, you get the best of both worlds: a fast, data-rich server render and precise islands of interactivity where they matter.

#react#next.js#rsc#performance

More in Frontend