RSC(React Server Components) 페이로드는 서버 컴포넌트를 실행한 결과(엘리먼트 트리, props, 클라이언트 컴포넌트 참조)를 네트워크로 보내려고 직렬화(Serialization)한 데이터다. 흔히 Flight 형식이라 부른다. HTML(HyperText Markup Language)이 아니라 React가 클라이언트에서 트리를 다시 만드는 데 쓰는 줄 단위 스트림이다. 세부 형식은 React 버전마다 바뀐다(아래는 2026년 기준의 대략적인 모양).
1:I["./LikeButton.js",["chunk-3f2.js"],"default"]
0:["$","div",null,{"className":"card","children":[
["$","h2",null,{"children":"제목"}],
["$","$L1",null,{"count":3}]]}]- 줄 = 청크:
ID:태그+JSON꼴이다. ID가 있어서 청크끼리 서로를 가리킬 수 있다 - 태그: 없으면 일반 데이터나 엘리먼트,
I는 클라이언트 모듈 참조,H는 CSS(Cascading Style Sheets)·폰트 미리 받기 힌트,E는 에러,D는 개발용 디버그 정보 $접두사:"$"는 엘리먼트 표시,"$L1"은 아직 안 온 청크 1의 지연 참조,"$@1"은 Promise,"$h"는 서버 함수 참조(이전 버전은"$F"),"$Sreact.suspense"는 심볼이다. 진짜$로 시작하는 문자열은$$로 이스케이프한다
엘리먼트 객체와의 대응
["$", type, key, props] 배열은 React 엘리먼트 객체 { $$typeof, type, key, props }를 그대로 옮긴 것이다. JSON(JavaScript Object Notation)으로 못 만드는 것만 바뀐다. $$typeof 심볼은 "$" 마커가 되고, 함수인 클라이언트 컴포넌트는 코드 대신 I 청크 참조($L1)가 된다. 서버 컴포넌트는 서버에서 이미 실행돼 사라지고, 반환한 엘리먼트들이 펼쳐져 담긴다. 그래서 클라이언트 컴포넌트에 넘기는 props는 직렬화할 수 있어야 한다.
스트리밍
먼저 $L1 같은 자리표시자를 보내고, 서버에서 그 데이터가 준비되면 같은 ID의 청크를 나중에 흘려보낸다. 클라이언트는 도착하는 대로 참조를 채운다. Suspense 경계가 자리표시자 자리다(스트리밍 SSR, Suspense). Next.js는 첫 로드 때 페이로드를 HTML 안의 self.__next_f.push(...) 스크립트로 넣고, 이후 이동 때는 페이로드만 따로 받는다.
같은 트리의 두 상태라고 보면 된다. 메모리 속 살아 있는 객체가 Virtual DOM이고, 그것을 네트워크로 옮기려고 문자열로 만든 것이 페이로드다. 직렬화와 원격 호출의 일반론은 RPC.