Back
Web Fundamentals

React Server Components: Zero-JS Server Rendering

Web Fundamentals
Build & Deployment: Monorepo, CI/CD, Strategies & Release SafetyState Management: Choosing the Right SolutionRedux: Predictable State Container (RTK + RTK Query)React Query (TanStack Query): Server State CachingData Fetching Patterns: REST, GraphQL, tRPC & Real-timeGraphQL Fundamentals for Frontend: Shape, Caching, and TradeoffsgRPC-Web Fundamentals: Browser Constraints and Proxy ModelCaching Strategies: Client, Server & EdgeData Normalization: Organizing State for PerformanceAPI Design Best Practices: Pagination, Errors, Versioning & Type SafetyAPI Versioning Strategies for Frontend CompatibilityPagination: Offset vs Cursor-BasedRate Limiting & API Resilience: Retries, Backoff, Jitter, IdempotencyHow Frontend Developers Can Handle Millions of API Requests Without Crashing EverythingBrowser Storage: Cookies, SessionStorage, LocalStorage, IndexedDBReal-time Communication: WebSockets, SSE & PollingWebRTC: Real-Time Communication in the BrowserCore Web Vitals: LCP, INP & CLSPerformance Optimization Trade-offsCritical Resource Prioritization: Optimize Loading OrderCode Splitting: Optimize Bundle Size with Dynamic ImportsTree Shaking: Eliminate Dead Code from Your BundleLazy Loading: Load Resources On-DemandResource Hints: Preload, Prefetch & PreconnectText Compression: Gzip and BrotliImage & Video Optimization: Modern Formats & TechniquesAdaptive Loading: Optimize for Device & NetworkList Virtualization: Render Large Lists EfficientlyWeb Workers vs Main Thread: Offloading Heavy WorkMemory Leaks in Frontend Apps: Detection & PreventionManaging Third-Party Scripts: Optimization StrategiesHow CDNs Work: Edge Delivery, Caching & PerformanceHTTP Caching Deep Dive: Cache-Control, ETag & RevalidationService Workers & Offline Strategy: Cache First, Network First & Update LifecyclePWA Fundamentals: Manifest, Installability & Offline UXCritical Rendering PathScript Loading: async vs deferEvent Loop: Understanding JavaScript Execution ModelJavaScript Module Systems: CJS vs ESM vs UMDDynamic Module Loading: import() FunctionImport on Interaction: Load When User InteractsImport on Visibility: Lazy Loading with IntersectionObserverBrowser Rendering Pipeline & Layout ThrashingRendering Strategies: CSR vs SSR vs SSG vs ISRStreaming SSR: Progressive HTML StreamingIslands Architecture: Independent Component HydrationReact Server Components: Zero-JS Server RenderingFramework Reactivity: React, Vue, Svelte & SolidHTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC) for Frontend PerformanceDNS Resolution: Path, TTL, Caching & Frontend ImpactCross-Site Scripting (XSS) AttacksCross-Site Request Forgery (CSRF) AttacksCORS Explained: Cross-Origin Resource SharingCORS Preflight in Practice: Credentials, Simple Requests & MisconfigurationsContent Security Policy (CSP)Why is HTTPS Secure? Understanding TLS/SSLAuthorization Best PracticesCookie Security & Session Hardening: SameSite, HttpOnly, Secure
mediumRendering & Browser Architecture

React Server Components: Zero-JS Server Rendering

TL;DRServer Components render on the server and stay out of client bundles. Client Components handle interactivity only where needed.
Very High Signal
Google
Meta
Netflix
Agoda
30-Second Answerstart every interview with this

React Server Components (RSC) allow you to render components on the server and exclude their code from the client JavaScript bundle. In frameworks like Next.js App Router, components are Server Components by default. Use 'use client' only for truly interactive parts. This dramatically reduces bundle size, hydration cost, and main-thread work.

Server Components = chef prepares and plates the food in the kitchen (server). Only the final plated dish is sent through the window. Client Components = the waiter (browser) gets some tools and instructions to handle final touches like seasoning or customer requests. You only ship tools for the parts that actually need them.

Request Arrives
Server Components render + fetch data
Client boundary reached
Minimal Client JS hydrates only interactive islands
Full interactivity

1Server Components

Run exclusively on the server. Can fetch data, access databases, read files, and keep secrets safe. Their output (HTML + serialized props) is sent to the client with no JavaScript cost.

page.tsxtsx
export default async function ProductsPage() {
  const products = await db.products.findMany();
  return <ProductList products={products} />;
}

2Client Components

Marked with 'use client'. Handle state, effects, event handlers, and browser APIs. Only these parts ship JavaScript and hydrate.

Button.tsxtsx
'use client';

export default function Button() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

3Composition & Boundaries

Server Components can render Client Components. Data flows from server to client via props. Keep client boundaries small and intentional.

4Data Fetching Advantages

Fetch directly in Server Components with native async/await. Parallel fetching with Promise.all is natural. No need for client-side loading states in many cases.

PropertyServer ComponentClient Component
Allowedasync/await, database accesshooks, events, effects
Js CostZeroFull bundle + hydration
Use CaseData fetching, static/read-only UI, server-only logicInteractivity, local state, browser APIs
Not AlloweduseState, useEffect, onClickDirect server-only APIs

Server Component

Allowed

async/await, database access

Js Cost

Zero

Use Case

Data fetching, static/read-only UI, server-only logic

Not Allowed

useState, useEffect, onClick

Client Component

Allowed

hooks, events, effects

Js Cost

Full bundle + hydration

Use Case

Interactivity, local state, browser APIs

Not Allowed

Direct server-only APIs

Common questions

  • ›“What are React Server Components and how do they differ from Client Components?”
  • ›“How does RSC reduce bundle size?”
  • ›“Explain data fetching in Server Components.”
  • ›“When would you use 'use client' in a Next.js app?”

What interviewers look for

  • Clear distinction between RSC and classic SSR
  • Understanding of bundle boundary and hydration impact
  • Practical composition patterns
  • Awareness of trade-offs (complexity vs performance)

Short answer (60 sec)

React Server Components render on the server and do not ship JavaScript to the client. They are the default in Next.js App Router. Use 'use client' only for interactive parts that need state, effects, or browser APIs. This keeps bundles small and reduces hydration cost.

Detailed answer (senior level)

RSC is a paradigm shift: it moves rendering and data logic to the server while keeping only truly interactive code on the client. Server Components can fetch data directly and pass props to Client Components. The real power is in reducing unnecessary client JavaScript. In practice, you keep the shell and data-heavy parts as Server Components and isolate small interactive islands behind client boundaries.

  • Putting everything in Client Components out of habit
  • Trying to use hooks inside Server Components
  • Making overly large client boundaries
  • Forgetting that props passed to Client Components must be serializable
  • Assuming RSC eliminates all JavaScript
Key Takeaways
  • ✓Server Components = zero client JS for non-interactive UI
  • ✓Client Components = only for state, events, and browser APIs
  • ✓'use client' creates a boundary in the module graph
  • ✓RSC excels at data fetching directly on the server
  • ✓Biggest win: dramatically smaller bundles and hydration cost
  • ✓Combine with Streaming SSR and Islands for optimal performance
  • ✓Measure client bundle size — not just render time
Previous TopicIslands Architecture: Independent Component HydrationNext Topic Framework Reactivity: React, Vue, Svelte & Solid

On this page