- Next.js
- Server Components & Boundaries
- The React Flight Protocol & RSC Wire Format
The React Flight Protocol & RSC Wire Format
The React Flight protocol is a compact, streaming text format used to serialize React Server Component trees over the wire. Instead of sending HTML or raw JavaScript, the server streams a chunked JSON-like stream containing module references for Client Components ($L), serialized props, and virtual DOM tags, enabling seamless client-side tree reconciliation without document reloads.
Learning Objectives
Inspect and interpret raw React Flight payloads (_rsc network requests) in browser DevTools.
Explain module references ($L) and how the client bundles load interactive chunks on demand.
Differentiate between raw HTML responses and the Flight stream during client-side navigation.
Understand how React reconstructs virtual DOM trees from streaming chunks.
Prerequisites & Background Knowledge
Why Interviewers Care
Elite-level interview topic demonstrating deep understanding of React 19 and Next.js compiler internals.
The Challenge
What is the React Flight protocol? Dissect a raw _rsc network response and explain how React uses it to update client UI without reloading HTML documents.
Code Architecture & Implementation
1// Sample raw response from a Next.js App Router navigation:2// GET /dashboard?_rsc=19xyz HTTP/1.13// Transfer-Encoding: chunked4// Content-Type: text/x-component56// Chunk 1: Client Component Module Reference ($L)7// Tells browser: "Load Client Component bundle at chunk 418"81:I["(app)/dashboard/Sidebar.tsx",["418","static/chunks/418.js"],"default"]910// Chunk 2: Server Component Virtual DOM Tree Definition11// "div" element with children, referencing Client Component $L1120:["$","div",null,{"className":"container","children":[13 ["$","$L1",null,{"title":"Analytics Sidebar"}],14 ["$","p",null,{"children":"Rendered on server with zero client JS!"}]15]}]1617// Chunk 3: Resolved Async Data Stream18// Emitted when a Suspense promise resolves192:{"data":{"userCount":4210,"status":"healthy"}}
Architectural Explanation
The React Flight Wire Format Explained
When a user clicks a <Link> in Next.js App Router, the browser does not request a new HTML document. Instead, it sends a request with an _rsc search parameter to fetch the Flight payload (Content-Type: text/x-component).
Key Elements of the Stream:
- Lines prefixed with
I(Module Imports):Declares a Client Component. It specifies the file path, the client JavaScript bundle chunk hash (1:I["(app)/dashboard/Button.tsx",["210","static/chunks/210.js"],"default"]static/chunks/210.js), and the export name. The browser downloads this chunk only if it is not already cached. - Lines prefixed with
$(React Elements):Serializes the virtual DOM tree. Notice0:["$","div",null,{"className":"card","children":["$","$L1",null,{"label":"Click"}]}]"$L1"references the Client Component declared in chunk 1. - Out-of-Order Promise Resolution:
When an async Server Component wrapped in Suspense resolves, its data is pushed as a separate line in the stream, and React merges it into the live DOM tree without resetting client component state!
Common Mistakes & Anti-Patterns
Assuming Next.js client-side navigation fetches raw HTML (it fetches the Flight payload).
Believing Flight payloads are standard JSON (they are newline-delimited streaming chunks).
Thinking Flight payloads contain executable JavaScript functions.
Interview Follow-Up Traps
Interviewer asks: "Why doesn't Next.js just return HTML on client navigation and use innerHTML?" Trap answer: HTML is faster. Correct answer: Replacing innerHTML wipes out all active client component state (e.g. focused inputs, open menus, animations). The Flight protocol allows React to diff the virtual DOM and update only the changed elements while preserving state.
Interviewer asks: "Is the Flight payload smaller or larger than raw HTML?" Trap answer: Always smaller. Correct answer: For pure text, it can be slightly larger due to serialization metadata, but it completely eliminates the need to download heavy JavaScript libraries for server components, saving hundreds of kilobytes overall.
Frequently Asked Questions
Does the Flight stream execute code in an eval() block?
No. The Flight client parser safely reconstructs virtual DOM objects without dynamic code evaluation.
What happens if a Client Component chunk fails to download during Flight streaming?
React triggers the nearest Error Boundary around that component.
Is the Flight protocol specific to Next.js or part of React core?
Flight is part of the official React 19 Server Components architecture, implemented by frameworks like Next.js.
How does Flight handle circular object references?
Circular references cannot be serialized across the RSC boundary and throw a serialization error.
