npm.io
0.2.4 • Published yesterdayCLI

react-render-board

Licence
MIT
Version
0.2.4
Deps
3
Size
289 kB
Vulns
0
Weekly
0
Install scriptsThis package runs scripts during installation (preinstall/install/postinstall)

react-render-board

npm version license React

React 앱의 실시간 렌더 트리를 Figma 같은 보드 위에 박스+선 다이어그램으로 시각화하는 dev 전용 도구.

React DevTools의 들여쓰기 리스트 뷰가 아니라, 실행 중인 컴포넌트 구조를 공간적으로 배치된 노드 다이어그램으로 보여줍니다. 새 코드베이스에 처음 들어온 사람이 전체 구조를 한눈에 파악하는 것을 목표로 합니다.

npm install --save-dev react-render-board   # postinstall이 번들러를 감지해 자동 설정
npm run dev                                   # 앱 우측 하단에 보드 버튼이 뜬다

목차


무엇이 다른가

도구 접근 한계
React DevTools 실행 중 트리를 텍스트 리스트로 강력하지만 "전체 그림"이 직관적으로 안 들어옴
CodeSee / 정적 분석 import 관계를 그래프로 실제 렌더 구조(children prop, Context, 포탈 등)와 불일치
react-render-board 실행 중 Fiber 트리를 공간 다이어그램으로 React 전용 · dev 전용 (아래 한계)

"실시간 렌더 트리 + Figma식 캔버스"라는 조합은 여러 팀이 시도했지만(React-Sight, Realize, Reactron 등) 모두 유지보수가 끊겼습니다. 이 조합은 현재 시장에서 비어 있습니다. 배경 조사는 docs/research/prior-art.md 참고.

대상 사용자: 매일 디버깅하는 베테랑이 아니라, 새 코드베이스에 처음 들어온 사람 — 온보딩, 코드 리뷰, 아키텍처 문서화, 신규 입사자 교육을 위한 도구입니다.


핵심 기능

구조 시각화
  • 실시간 렌더 트리 — React 커밋마다 Fiber 트리를 읽어 보드에 반영. 앱이 리렌더되면 보드도 따라 갱신됩니다.
  • 도메인별 그룹 프레임 — 컴포넌트를 소스 파일 경로 기준으로 묶어 색이 다른 프레임으로 표시. "폴더로 묶기" 토글로 파일 그룹을 상위 폴더로 2단 중첩(folder › file › component).
  • Semantic zoom — 줌아웃하면 지도 모드(도메인 개요), 줌인하면 상세 모드(개별 컴포넌트). "지도에서도 상세" 토글로 줌아웃해도 화면 안 그룹의 내부를 유지.
  • tidy-tree 배치 — 부모를 자식 스팬의 중앙 위에 놓는 대칭 트리 레이아웃. 좌→우가 렌더 순서, 위→아래가 깊이.
  • 리스트 접기 — 같은 부모 밑 같은 종류 형제가 5개 이상이면 대표 하나 + "×N" 배지로 접어 구조를 안정화.
  • host 노드 기본 숨김 — DOM 뷰어가 아니라 "컴포넌트 보드"라는 정체성 유지 (토글 가능).
보드 실제 화면 양방향 인터랙션
  • 노드 → 화면: 보드 노드를 클릭하면 대응하는 실제 DOM 요소에 하이라이트. 더블클릭하면 그 요소로 스크롤 이동.
  • 화면 → 노드: 앱에서 Alt(⌥)+클릭하거나 "요소 선택" 모드로 클릭하면 대응하는 보드 노드로 자동 이동+강조. (평소 클릭은 전혀 건드리지 않아 앱 조작을 방해하지 않음.)
  • hover 프리뷰 — 픽 모드에서 커서 아래 요소를 실시간 강조("클릭하면 이게 선택된다"를 미리 보여줌).
탐색 · 필터
  • 검색 하이라이트 + 자동 이동 — 컴포넌트명/도메인명 검색 시 매치 강조 + 나머지 흐림 + 카메라 자동 이동. 접힌 그룹 안에 매치가 있으면 강제로 펼침.
  • 그룹 + 개별 필터 — "매치만 표시"로 매치 없는 그룹/노드를 아예 렌더에서 제외.
  • 그룹 접기/펼치기, 우클릭 컨텍스트 메뉴(그룹: 접기·확대 / 컴포넌트: 화면에서 보기·검색), 캔버스 스티키노트(자유 배치 메모, localStorage 영속).
데이터 흐름 (실험적)
  • props 흐름 추적 + 변경 잔상(afterglow) — 노드 선택 시 우선순위 정렬 props 패널, prop 클릭 시 자손으로의 참조 추적을 간선 경로로 강조, props 변경이 부모→자식 간선을 타고 흐르는 애니메이션. (Context/외부 스토어 추적은 보류.)
시각 언어
  • 도형 = 역할: 라우트 진입 노드는 6각형, 포탈 , Suspense 경계 , 에러 바운더리 🛡.
  • 손그림 정체성 — Excalidraw풍 rough.js 스케치 테두리 (노드 수 무관 O(1) 정적 이미지).
  • 간선 정리 — 그룹 내 간선은 깊이별 감쇠, 그룹 간 간선은 직교 배선(프레임을 장애물로 회피) + 출발→타깃 도메인 색 그라데이션, hover 시 혈통(조상+자손) 점등.
  • 다크모드 + 도메인별 팔레트 — 그룹 이름 해시 기반 8색 고정 팔레트가 프레임·노드·미니맵에 일관 적용.
  • 도킹 패널 — 화면 하단(기본)/좌/우 사이드바로 위치 전환 + 드래그 크기 조절 (localStorage 영속). 오버레이 전용 — 계측 대상 앱의 레이아웃/CSS는 절대 건드리지 않습니다.
  • 고빈도 안정성 — store 갱신을 30Hz로 스로틀하고 안 바뀐 노드는 참조를 재사용해 60240Hz 앱에서도 깜빡임을 억제.

설치

dev 전용 도구입니다 — 프로덕션 빌드엔 주입되지 않습니다(다중 가드, 동작 원리 참고).

npm / yarn
npm install --save-dev react-render-board
npm run dev

설치 직후 postinstall이 번들러를 감지해 설정을 자동으로 넣습니다. 그대로 npm run dev만 실행하면 앱 우측 하단에 보드 버튼이 뜹니다.

pnpm

pnpm은 처음 보는 패키지의 설치 스크립트를 기본 차단합니다(공급망 보안 정책 — esbuild·sharp 등 설치 스크립트가 있는 대부분의 유명 패키지도 동일하게 겪는 pnpm 표준 절차이며, 이 패키지만의 특이사항이 아닙니다). 한 번만 승인하면 됩니다:

pnpm install --save-dev react-render-board
pnpm approve-builds --all   # 비대화형 일괄 승인. 고르고 싶으면 `pnpm approve-builds`
npm run dev

&&로 이어 붙이지 마세요. ignored-builds가 걸리면 pnpm installexit code 1을 돌려주므로(패키지 자체는 정상 설치됨) && 뒤의 approve-builds가 조용히 스킵됩니다. 위처럼 줄을 나눠서(또는 ;로) 실행하세요.

수동 설정 (init)

자동 설정이 스킵됐거나 다시 확인하고 싶을 때:

npx react-render-board init

init(자동이든 수동이든)이 번들러를 감지해 설정을 구성하고, 실행 후 앱 우측 하단 버튼을 누르면 하단 도킹 패널에 실시간 렌더 트리가 그려집니다. 앱 소스 코드는 한 줄도 건드리지 않으며(설정 파일만 수정), 프로덕션에는 들어가지 않습니다.


번들러별 설정

init이 자동으로 하지만, 무엇을 하는지 알고 싶거나 직접 넣고 싶을 때 참고하세요.

번들러 init이 하는 일 수동 설정
Vite vite.configplugins에 플러그인 추가 아래 ①
Next.js / Turbopack 루트 layout.tsx에 조기 <head> 스크립트 + RenderBoardClient 배선 아래 ②
webpack webpack.configwithRenderBoard(...)로 래핑 아래 ③

① Vite

// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { rrbInjectPlugin } from 'react-render-board/vite';

export default defineConfig({
  plugins: [react(), rrbInjectPlugin()],   // dev(serve)에서만 활성
});

② Next.js / Turbopack — Turbopack엔 플러그인 API가 없어 루트 layout.tsx<head>에 조기 <script>를 넣고(초기 커밋부터 버퍼링), <body>에 클라이언트 컴포넌트를 배선합니다. npx react-render-board init이 이 배선과 RenderBoardClient.tsx 생성을 자동으로 처리합니다(수동 편집 권장 안 함).

③ webpack

// webpack.config.js
const { withRenderBoard } = require('react-render-board/webpack');

module.exports = withRenderBoard({ /* 기존 config */ });

보드 스타일은 0.2.2부터 런타임이 스스로 주입합니다 — 어떤 번들러에서도 별도 CSS 설정이 필요 없습니다(css-loader 불필요). 예전 안내로 앱 엔트리에 import 'react-render-board/style.css'를 추가했다면 지워도 됩니다(있어도 무해).


동작 원리

소스 코드(.jsx 파일)를 파싱하지 않습니다. 대신 브라우저에서 실행 중인 React 앱이 메모리에 만들어 둔 Fiber 트리를 실시간으로 읽습니다. React가 개발용으로 열어 둔 window.__REACT_DEVTOOLS_GLOBAL_HOOK__을 통해 접근합니다.

3-레이어 구조 (자세한 내용은 docs/architecture.md):

① 훅킹        bippy로 커밋마다 Fiber 트리 접근 + DOM↔Fiber 양방향 매핑
   ↓
② 데이터      Fiber → 정규화된 RenderNode 트리, 소스 경로 기반 groupHint 해석
   ↓
③ 시각화      React Flow(@xyflow) 기반 그룹 프레임 + 노드 + 직교 간선, semantic zoom
  • 훅킹은 직접 구현하지 않고 검증된 라이브러리(bippy)에 위임합니다.
  • 실제 제3자 앱 3개(excalidraw · berry-admin · shadcn-admin)에서 콘솔 에러 0건으로 검증됐습니다.
dev 전용 가드

프로덕션 유출을 막는 다중 가드가 있습니다: Vite 플러그인 apply: 'serve', Next process.env.NODE_ENV 정적 제외, 주입 레이어가 세우는 런타임 신호 __RRB_DEV__. 프로덕션 번들에는 어떤 형태로도 들어가지 않습니다.


프로그래밍 방식 API (커스텀 통합)

init/postinstall 자동 배선 대신 직접 통합하고 싶을 때. 공개 API는 3-레이어 각각의 진입점만 노출합니다(내부 구현은 재수출하지 않음).

import { createRoot } from 'react-dom/client';
import {
  createRenderStore,
  startFiberInspector,
  createInteractionStore,
  startDomClickBridge,
  BoardOverlay,
} from 'react-render-board';
import 'react-render-board/style.css';   // 라이브러리 소비 시 CSS를 직접 import해야 함

const store = createRenderStore();
const interactionStore = createInteractionStore();

startFiberInspector(store, subjectContainer);              // ① 훅킹 시작
startDomClickBridge(subjectContainer, interactionStore);   // 역방향(DOM→보드) 인터랙션, 선택

createRoot(overlayHost).render(
  <BoardOverlay store={store} interactionStore={interactionStore} />
);

주요 export:

심볼 레이어 역할
createRenderStore 데이터 구독 가능한 렌더 트리 스토어
startFiberInspector 훅킹 커밋마다 Fiber를 읽어 스토어에 반영
startDomClickBridge, findFiberIdForElement, resolveHostElements 훅킹 DOMFiber 매핑(역방향 인터랙션)
Canvas, BoardOverlay, DomHighlightOverlay 시각화 보드 UI 컴포넌트
createInteractionStore 시각화 노드DOM 인터랙션 상태
createAfterglowStore, readFiberProps, trackReferenceInDescendants 시각화 props 흐름/변경 잔상(선택)

타입: RenderNode, RenderSnapshot, FiberKind, RenderStore, InteractionStore, PropRow 등도 함께 export됩니다. 전체 목록은 src/index.ts 참고.


호환성

추가 스키마 변경 없이 다음 React 패턴을 커버합니다(실제 앱으로 검증):

  • 함수형 / class 컴포넌트, 에러 바운더리
  • Concurrent 기능: useTransition, use() + Suspense
  • React.lazy 코드 스플리팅 경계
  • 포탈(논리적 부모 아래 정확히 배치)
  • memo / forwardRef(정확한 이름 표시)

React 18 · 19 지원 (peerDependencies ^18 || ^19).


요구사항 · 한계

  • React 전용. 기술 스택 전체가 React Fiber 내부 구조에 묶여 있습니다(구조적 제약이며 초기 선택 사항이 아님). Vue/Svelte 등은 각 프레임워크별 별도 구현이 필요합니다.
  • dev 전용. getSource 기반 그룹핑이 개발 빌드에서만 동작하며, 프로덕션엔 주입되지 않습니다.
  • 규모.중 규모(수백 개 노드)는 견고합니다. 대규모(수천9,000+ 노드)도 뷰포트 기반 부분 렌더링으로 응답성이 평탄화되지만(P0~P4 수정 반영), 그룹이 매우 많을 때 지도 모드 라벨 겹침(declutter)은 부분 완화 상태입니다.
  • 고빈도 갱신. 실질 한계는 30Hz 스로틀 캡입니다(60240Hz 앱도 동작하되 갱신이 스로틀됨).
  • Node.js ≥ 18.
  • 런타임 의존성: @xyflow/react, bippy, roughjs.

프로젝트 상태

npm 배포됨 (0.2.0, MIT). 엔진(훅킹→데이터→시각화) 완성 + 3개 번들러(Vite/Turbopack/webpack) install→캔버스 실측 완료. vitest 유닛 테스트 335개.

  • 기술·UI 검증, 라이브 MVP, 실제 제3자 앱 검증(excalidraw / berry-admin / shadcn-admin)
  • 확인된 결함 5건(P0~P4) 해소 + 테스트 커버리지 + 패키지 배포 준비
  • 배포 진입 경험: postinstall 자동 설정 + 3개 번들러 원커맨드
  • 실사용/도그푸딩 + 생존 전략 결정 (완성 우선 기조로 의도적 보류 중)

전체 현황은 docs/project-status.md를 참고하세요 — 지금까지의 모든 조사·실험·검증·결정을 요약한 살아있는 스냅샷이며, 개별 ADR로 링크됩니다.


문서

문서 내용
docs/project-status.md 현황 종합 — 검증 결과·확인된 결함·방향 (여기부터 읽기)
docs/vision.md 풀려는 문제와 목표
docs/architecture.md 3-레이어 구조와 동작 원리
docs/ui-philosophy.md UI 철학과 레퍼런스
docs/roadmap.md 단계별 계획
docs/research/ 배경 조사(선행 프로젝트·기술 옵션)
docs/decisions/ 주요 의사결정 기록(ADR)

개발 (이 레포에서)

npm run dev          # 라이브 MVP (좌: 계측 대상 데모 앱, 우: 실시간 보드)
npm run build        # 타입체크 + 빌드
npm run typecheck    # 타입체크만 (tsc -b) — 커밋 전 1회 권장
npm run build:lib    # 라이브러리 빌드 (src/index.ts 공개 API → dist-lib/)
npm run lint         # oxlint
npm run test         # 레이어별 유닛 테스트 (vitest)
npm run verify       # 자체 fixture 회귀 검증 (Playwright, dev 서버 실행 중이어야 함)

npm run test(vitest)는 타입을 스트립하므로 타입 오류를 못 잡습니다. 커밋 전 npm run typecheck를 1회 돌리세요.


라이선스

MIT yoonjaehong26

Keywords