Logan.

2026-05-15

Storybook 도입 1년 회고 안전망의 모양

RN 프로젝트에 Storybook을 도입하고 1년. 채워진 칸, 비어있는 칸, 그리고 다시 시작한다면 다르게 할 결정들.

by Logan·12분 읽기·part 7 of 본격 Storybook 도입·#storybook #retrospective #react-native

안녕하세요, 로건입니다 👋

긴 시리즈도 이제 마지막 편입니다. 여기까지 오신 분들 정말 감사해요.

1년 전 처음 RN 프로젝트에 Storybook을 셋업하던 그 오후를 기억해요. 그때 동료가 던졌던 질문 — "그거 어차피 HTML로 렌더하는 거잖아요?" — 에 한 줄로 답하지 못했던 그 자리에서 시작된 시간이었어요. 지금은 그 한 줄을 가지고 있습니다.

이 마지막 글에서는 1년 운영하고 손에 남은 안전망의 전체 모양을, 그리고 아직 못 채운 칸들다시 도입한다면 다르게 할 결정 세 가지를 정직하게 정리해볼게요.

안전망의 최종 모양

먼저 우리 팀의 테스트 레이어 분담을 한 번에 보여드릴게요.

┌─────────────────────────────────────────────────────┐
│ Layer 5: Device QA / Detox                            │
│   - gesture, IME, perf, 네이티브 모듈                  │
│   - 비싸지만 본질, 디바이스에서만 잡힘                 │
│   - 빈도: release 전 / sprint 끝                       │
├─────────────────────────────────────────────────────┤
│ Layer 4: Chromatic 시각 회귀                            │
│   - 픽셀 단위 diff, PR마다 자동                         │
│   - TurboSnap으로 영향받은 스토리만 캡처                  │
│   - 빈도: PR마다 자동, ~3분                             │
├─────────────────────────────────────────────────────┤
│ Layer 3: Storybook play 함수                            │
│   - JS 레이어 로직 (props/state/handler)                │
│   - Tier 1, 2 컴포넌트 (60개 정도)                       │
│   - 빈도: PR마다 자동, ~1분                             │
├─────────────────────────────────────────────────────┤
│ Layer 2: Storybook 시각 카탈로그                          │
│   - argTypes 콘트롤, Designs 탭에 figma 연결              │
│   - 디자이너·QA·개발자 합의 도구                          │
│   - 빈도: 항상 (사이드바)                                │
├─────────────────────────────────────────────────────┤
│ Layer 1: jest unit                                     │
│   - 순수 함수, 유틸리티                                   │
│   - 빈도: PR마다 자동, ~10초                              │
└─────────────────────────────────────────────────────┘

위로 갈수록 비싸지고, 본질에 가까워져요. 아래로 갈수록 싸고, 자주 돕니다. Storybook은 Layer 2~4를 차지하는 그물입니다. 모든 칸을 채우는 것이 목표가 아니라, 각 칸의 주인이 누구인지 분명히 하는 것이 안전망 운영의 본질이에요.

play 함수의 Tier 분류 — 모든 곳에 달지 않는다

이게 1년 운영하면서 가장 늦게 안정화된 부분이에요. 처음엔 모든 컴포넌트에 play 함수를 달려고 했는데, 작성 비용이 도입 자체를 좌초시킬 뻔했거든요. Tier로 나눈 다음에 합리적이 됐어요.

Tier정의play 적용예시
Tier 1핵심 사용자 경로필수Button, FormField, BottomSheet
Tier 2자주 회귀 발생 영역권장ToggleSwitch, Tabs, Stepper
Tier 3보조 UI, 표시 전용안 함Badge, Divider, Spinner
Showcase갤러리 grid안 함 (마찰)AllTones, AllSizes

Tier 1 + 2 합쳐서 60개 정도 컴포넌트에만 play를 달았어요. 모든 컴포넌트에 달았다면 작성 시간도 유지보수 부담도 무거웠을 겁니다. 안전망의 그물눈을 조밀하게가 아니라 적절하게 짜는 것이 핵심이었어요.

1년간 만들어진 산출물

숫자로 정리하면 이래요.

항목수치
컴포넌트 스토리200+
play 인터랙션 테스트60+
Figma 자동 변환 스토리80+
일괄 삭제한 페이지 스토리 (3편)-106
Chromatic baseline200+ 스냅샷
월 평균 PR 자동 검수~80건
Chromatic이 잡아낸 실제 회귀~15건

마지막 줄이 가장 중요해요. 1년 동안 Chromatic이 잡아낸 실제 회귀가 15건이었습니다. 그 15건이 PR 머지 전에 잡히지 않았다면 어떻게 됐을지 상상해보세요. 디바이스 QA로 갔다가 운 좋게 발견되거나, prod 배포 후 사용자가 발견했을 거예요. 그 한 건당의 비용을 생각하면, 1년 운영 비용은 진작에 회수됐습니다.

아직 못 채운 칸들

이게 가장 정직하게 적어두고 싶은 부분이에요. 시도했는데 못 했거나, 의도적으로 미뤄둔 영역들이요.

영역상태이유
addon-a11y 자동 audit⏳ 미시작우선순위 낮음. 디바이스 QA에서 함께 검수 중.
test-runner CI 통합 (Tier 2까지)🔄 일부만Tier 1만 자동, Tier 2는 수동 트리거.
Living Style Guide (MDX 문서)⏳ 미시작argTypes 콘트롤로 충분하다는 판단.
디자인 토큰 시각화 페이지🔄 부분만Visual Builder로 부분 대체.
Detox e2e와의 dual 라벨링⏳ 미시작같은 시나리오를 양쪽에 두면 mock 무한 회귀 위험.
iOS vs Android 별도 베이스라인⏳ 미시작우리 케이스에서는 차이가 작아 무료 플랜 비용 우선

빈 칸을 모두 채우는 게 목표가 아니라, 각 칸이 누구의 책임인지 명시하는 것이 안전망 운영의 본질이라고 1편부터 6편까지 반복해서 말씀드렸어요. 이 표가 그 메시지의 가장 정직한 증거입니다.

다시 도입한다면 다르게 할 결정 세 가지

이게 마지막 정리예요. 1년을 다시 시작한다면 어떻게 다르게 할까라는 질문에 솔직하게 답해볼게요.

결정 1 — 페이지 스토리는 처음부터 시작하지 않는다

3편에서 한 번에 지운 그 106개 페이지 스토리. 다시 시작한다면 그 시간 전체를 절약하고 컴포넌트 스토리에 집중하겠어요. 처음엔 "1:1 매칭이 가능하지 않을까?" 하는 환상이 있었는데, mock 무한 회귀의 함정이 너무 명백했어요. 어떤 영역은 처음부터 디바이스 QA에 맡기는 게 답이라는 걸 가장 빨리 인정하는 게 1년차의 최선이었을 거예요.

결정 2 — Chromatic은 1주차에 Pilot으로 켠다

6편에서 단계적으로 풀었던 Pilot 단계를 2개월 뒤에야 시작했어요. 다시 시작한다면 첫 PR 머지하기 전에 Pilot을 켜겠어요. 빠르면 빠를수록 false positive 패턴을 빨리 발견하고, 도입 자체의 ROI를 한 자릿수 PR 만에 증명할 수 있어요. 그게 팀의 신뢰를 끌어올리는 가장 빠른 방법이에요.

결정 3 — 스토리 작성 표준을 공유 문서로 만든다

2편에서 정리한 한 줄 규칙들 — argTypes 전수 노출, 대표 스토리만 play, StyleSheet.create만, shim은 고치지 말기 등 — 이게 사실 내 머릿속에만 있었어요. 신규 합류한 분이 똑같은 실수를 다시 하시더라고요. 다시 시작한다면 첫 컴포넌트 스토리를 짤 때 이 규칙들을 사내 위키에 박아두는 것부터 하겠어요. 도구가 자동으로 강제할 수 있는 규칙은 ESLint 룰로, 사람만 결정할 수 있는 규칙은 PR 리뷰 체크리스트로요.

그리고 한 줄

1년이라는 시간이 정말 빨리 갔어요. 처음엔 "Storybook 도입"이라는 한 줄짜리 OKR이었는데, 끝나고 보니 팀이 디자인을 검수하는 방식, PR이 머지되기 전에 거치는 단계, 디자이너와 개발자가 의사소통하는 도구가 다 같이 바뀌어 있더라고요.

만약 여러분이 비슷한 갈림길에 서 계신다면, 마지막으로 한 줄 드리고 싶어요.

도구가 아니라 정책이 안전망을 만듭니다.

Storybook을 깔고, Chromatic을 붙이고, play 함수를 짜는 건 일주일이면 됩니다. 그런데 어떤 회귀를 잡을지, 어떤 회귀를 안 잡을지, 합격 받은 스토리를 어떻게 보호할지, false positive를 어떻게 줄일지 — 이런 정책들이 정착하는 데 1년이 걸렸어요. 그 정책들이 모여서 지금의 그물이 됐습니다.

만약 여러분도 RN 프로젝트에 Storybook 도입을 고민 중이시라면, 도구 자체보다 정책 한 묶음을 같이 설계하시는 걸 추천드려요. 시리즈에서 풀었던 한 줄 규칙들이 그 시작점이 될 수 있을 거예요. 그리고 안 짤 영역을 처음부터 정직하게 비워두세요. 그게 일주일 뒤에 후회를 가장 적게 남기는 결정이더라고요.

긴 시리즈 읽어주셔서 다시 한 번 감사합니다. 안전망이라는 단어가 처음보다 조금 더 손에 잡히는 모양으로 다가왔으면 좋겠어요. 다음에 또 어디선가, 다른 글로 인사드릴게요.

related — in series · 본격 Storybook 도입