첫 번째 프로토타입

112025년 08월 26일3

코드네임 ‘React 19’가 선언된 후, 팀의 분위기는 열띤 토론장에서 차가운 개발 현장으로 바뀌었다. 개념은 세워졌지만, 그것을 실제 동작하는 코드로 구현하는 것은 완전히 다른 차원의 문제였다. 그리고 그 누구보다 먼저, 앤드류 클라크가 키보드 위로 몸을 숙였다.

그는 며칠 밤낮으로 코드에 몰두했다. 목표는 단 하나, 세상에서 가장 단순한 서버 컴포넌트를 만들어내는 것이었다.

그가 만든 것은 Note.server.js라는 이름의 파일이었다. 이 컴포넌트의 역할은 지극히 간단했다. 서버의 특정 경로에 있는 note.txt 파일을 읽어서, 그 내용을 div 태그 안에 담아 보여주는 것.

// Note.server.js 
import fs from 'fs';

function Note() {
  const content = fs.readFileSync('note.txt', 'utf8');
  return <div>{content}</div>;
}

이 몇 줄의 코드는 기존 React의 상식으로는 절대 불가능한 일이었다. 브라우저에서 실행되는 클라이언트 코드는 서버의 파일 시스템에 직접 접근할 권한도, 방법도 없었다. 하지만 이 컴포넌트는 서버에서 실행될 것이기에, fs 같은 Node.js의 기본 모듈을 자유자재로 사용할 수 있었다.

진짜 문제는 지금부터였다. 이 컴포넌트의 렌더링 결과물을 어떻게 클라이언트에 전달할 것인가?

단순히 HTML로 변환해서 보내는 것은 SSR과 다를 바 없었다. 앤드류가 원한 것은 그 이상이었다. 그는 서버 컴포넌트와 클라이언트 컴포넌트가 뒤섞인 복잡한 트리 구조 전체를 표현할 수 있는 새로운 데이터 형식이 필요했다.

그는 밤을 새워 새로운 직렬화(Serialization) 포맷을 설계했다. 그것은 HTML도, JSON도 아니었다. React만이 이해할 수 있는 일종의 ‘명령어 스트림’에 가까웠다.

["div", { "className": "note" }, "파일의 내용..."]

이런 식의 데이터 조각들이었다. “div를 그려라. 클래스 이름은 note다. 그 안의 텍스트는 이것이다.” 클라이언트의 React는 이 명령어들을 수신하여, 마치 지시를 받는 로봇처럼 화면에 UI를 조립해냈다.

수많은 실패와 디버깅 끝에, 마침내 그 순간이 왔다. 앤드류는 로컬 서버를 실행하고, 떨리는 손으로 브라우저에 주소를 입력했다.

엔터.

화면에 나타난 것은 투박하기 짝이 없는 텍스트 한 줄이었다. CSS도 적용되지 않은, 못생긴 div 태그 안에 note.txt 파일의 내용이 그대로 박혀 있었다. 허점투성이였고, 수많은 엣지 케이스는 고려조차 되지 않았다.

하지만 그 순간, 앤드류는 심장이 멎는 듯한 전율을 느꼈다.

“됐다….”

성공이었다.

서버의 파일을 직접 읽는 컴포넌트. 그 컴포넌트의 자바스크립트 코드는 단 한 바이트도 클라이언트로 전송되지 않았다. 오직 렌더링 결과에 대한 ‘지시서’만이 네트워크를 건너왔을 뿐이다. 이론으로만 존재하던 개념이, 그의 눈앞에서 실제로 동작하는 프로토타입으로 증명된 순간이었다.

그는 즉시 팀 채팅방에 메시지를 남겼다.

“다들 이것 좀 봐줘. 방금 첫 번째 서버 컴포넌트가 렌더링됐어.”

메시지를 확인한 팀원들이 하나둘 가상 회의실로 모여들었다. 앤드류의 화면 공유를 통해 투박한 결과물을 확인한 그들의 입에서 짧은 탄성이 터져 나왔다. 그것은 단순히 텍스트 한 줄이 아니었다. React 19라는 거대한 프로젝트의 첫 번째 벽돌이 놓이는 역사적인 장면이었다. 꿈이 현실이 되는 순간이었다.