나는 왜 Storybook을 애자일 도구로 사용하기로 했는가
Storybook을 단순한 컴포넌트 문서가 아니라 직접 조작할 수 있는 제품 시나리오와 빠른 피드백을 위한 애자일 도구로 활용한 경험입니다.
Storybook은 보통 UI 컴포넌트를 모아두는 문서화 도구로 소개된다. 버튼의 크기와 색상, 입력창의 상태, 모달의 종류를 한곳에서 확인하는 식이다. 나도 처음에는 비슷하게 사용했다. 그런데 실제 제품을 만들면서 더 답답했던 건 컴포넌트 관리가 아니었다. 기획자와 디자이너, 개발자가 같은 결과물을 너무 늦게 본다는 점이었다.
디자인은 Figma에 있고 구현한 화면은 개발자의 로컬 환경에 있었다. 백엔드 API가 준비되지 않으면 화면을 제대로 보여주기도 어려웠다. 다른 사람이 결과를 확인할 때쯤에는 구현이 상당히 진행된 뒤였고, 그때 의견이 달라지면 이미 만든 코드를 다시 고쳐야 했다. 일은 빠르게 진행하고 있었지만 제품을 빠르게 확인하고 있지는 않았다.
작업을 잘게 나눠도 피드백은 늦을 수 있다
애자일하게 일한다고 하면 짧은 스프린트와 작은 작업 단위를 먼저 떠올린다. 하지만 개발 티켓을 잘게 쪼갠다고 중요한 판단까지 빨라지지는 않는다. 개발자는 하루 단위로 작업을 나눠도 이해관계자가 2주 뒤에야 결과를 볼 수 있다. 칸반 보드에서 티켓이 빠르게 이동하더라도 사용자가 보게 될 화면이 마지막에야 나타난다면 제품에 대한 피드백은 여전히 늦다.
내가 애자일에서 중요하게 생각한 것은 피드백을 받을 수 있는 시점이었다. 완성된 기능을 보여주고 승인받기보다 아직 쉽게 바꿀 수 있을 때 결과물을 꺼내놓고 싶었다. 회의 자료나 설명만으로는 부족했다. 직접 보고 조작할 수 있어야 했다. 그 용도로 Storybook을 쓰기 시작했다.

컴포넌트 목록을 사용자 흐름으로 바꿨다
처음에는 메인 화면의 상태를 스토리 하나씩 나열했다. 응모 횟수, 오전·오후 출석, 출석 완료, 첫날, 두 배 적립일, 보상일, 긴 문구가 들어간 화면 등을 각각 만들었다. 그렇게 쌓인 메인 화면 스토리가 22개였다.
목록은 길었지만 제품이 어떻게 움직이는지 파악하기는 어려웠다. 각각은 특정 순간을 고정한 정적 화면이었고, 버튼을 눌러도 다음 상태로 이어지지 않았다. 출석한 뒤 화면이 어떻게 바뀌는지 보려면 여러 스토리를 오가며 머릿속으로 흐름을 이어 붙여야 했다. 확인할 조건이 늘어날수록 스토리 수도 빠르게 불어났다. 화면은 많이 준비돼 있는데 정작 제품을 사용해 볼 수는 없었다.
그래서 상태마다 스토리를 추가하는 방식을 그만두고, 화면을 결정하는 조건을 Storybook의 컨트롤로 꺼냈다.

메인 화면에서는 회차 상황, 레이아웃 스트레스, 첫 출석 회차를 각각 선택할 수 있다. 회차 상황에서는 첫날인지, 평범한 회차인지, 보상일인지 고른다. 레이아웃 스트레스에서는 Figma에 있는 기본값뿐 아니라 문구가 길거나 데이터가 비어 있는 경우도 선택한다. 첫 출석 회차는 오전과 오후 중 하나를 고른다.
기존에 22개로 나뉘어 있던 메인 화면 스토리는 이 축을 조합하는 시나리오 중심의 스토리 3개로 정리됐다. ‘보상일이면서 공지 제목이 긴 화면’처럼 이전에 따로 만들지 않았던 조합도 컨트롤을 바꾸면 바로 볼 수 있다. 스토리 개수를 줄이는 게 목적은 아니었다. 정적인 화면을 하나씩 구경하던 방식에서 조건을 바꾸고 직접 눌러보는 방식으로 옮기고 싶었다.
무엇을 컨트롤로 만들지 기준을 세웠다
모든 상태를 Storybook 컨트롤로 노출하면 화면을 빨리 둘러보기는 편하다. 하지만 실제 사용자 흐름과 다른 지름길이 생긴다. 그래서 상태를 하나씩 놓고 물었다.
사용자가 이 화면 안에서 직접 만들 수 있는 상태인가?
회차 상황이나 서버가 판정한 결과, 오전과 오후 같은 시간 조건은 화면을 눌러 바꿀 수 없다. 이런 값은 Storybook 컨트롤로 제공했다. 반면 팝업 열기, 출석하기, 응모 횟수 소진, 입력값 변경처럼 사용자의 행동으로 생기는 상태는 실제 화면을 눌러 도달하게 했다. 팝업이 열린 상태를 컨트롤 하나로 곧장 띄우면 편하지만, 그 과정에서 빠진 동작은 확인할 수 없기 때문이다.
이를 위해 Storybook 안에 작은 상태 머신을 조립했다. 출석 버튼을 누르면 출석 완료 팝업이 열리고 화면의 출석 상태가 바뀐다. 응모하기를 누르면 확인 팝업과 미션 이동 안내가 차례로 나타나며, 마지막 단계까지 진행해야 남은 응모 횟수가 줄어든다. 서버와 라우터가 맡는 역할 일부를 스토리가 대신하고 있지만 사용자가 보게 될 흐름과 상태 변화는 실제 제품에 맞췄다.
컨트롤은 화면을 건너뛰기 위한 장치가 아니다. 사용자가 직접 만들 수 없는 시작 조건을 고르는 장치다.
MSW 응답을 바로 바꿀 수 있는 도구를 만들었다
화면 상태를 미리 준비한 props로만 확인하는 데에는 한계가 있었다. API 응답이 비어 있거나 오류가 났을 때 화면이 어떻게 달라지는지 보려면 매번 목 코드나 픽스처를 고쳐야 했고, 프론트엔드에 익숙하지 않은 사람은 직접 시험하기도 어려웠다. 그래서 Storybook에 MSW 응답을 바로 오버라이드할 수 있는 도구를 추가했다.

패널에는 스토리에서 발생한 요청과 현재 응답이 표시된다. 여기서 상태 코드와 응답 본문을 직접 수정해 적용하면 컴포넌트가 다시 마운트되고, 같은 요청을 바뀐 응답으로 실행한다. 원래 응답으로 되돌리는 작업도 패널에서 바로 할 수 있다.
예를 들어 /v2/banners의 응답을 빈 배열로 바꾸면 배너가 없는 화면을 곧바로 확인할 수 있다. 상태 코드를 오류로 바꾸면 실패 상태가 나타나고, 필드 구조나 값이 달라졌을 때 화면이 어떻게 반응하는지도 시험할 수 있다. 이 과정에서 코드를 고치거나 Storybook을 다시 실행할 필요는 없다.
백엔드 개발자도 실제 API를 수정하기 전에 예상 응답을 이 패널에 넣어볼 수 있다. 계약 변경이 UI에 어떤 영향을 주는지 먼저 확인하고 필요한 예외 처리나 빈 상태를 함께 논의할 수 있다. 준비된 목 화면을 보는 데서 그치지 않고, 응답을 직접 바꾸며 프론트엔드와 백엔드 사이의 경계를 시험할 수 있게 된 것이다.

화면을 일찍 보여주는 것만으로는 해결되지 않았다
공유 시점을 앞당겨도 피드백을 전달하기가 불편하면 오래 쓰기 어렵다. “오른쪽 위에 있는 버튼을 조금 내려 주세요”라는 요청은 화면이 바뀌면 금방 모호해진다. 어떤 버튼인지 다시 물어야 하고, 수정한 뒤에는 어디에서 결과를 확인할지도 알려줘야 한다. 이 과정을 줄이려고 Storybook에 요소 집기 도구를 추가했다.
요소 집기를 켜고 화면에서 고치고 싶은 부분을 클릭하면 현재 스토리와 컨트롤 값, 선택한 요소, 셀렉터, Storybook 주소가 함께 복사된다. 처음에는 이 정보를 코드 조각처럼 만들었다. 개발자가 읽기에는 익숙했지만 다른 직군이 전달하기에는 불편했다. 나중에는 사람이 읽을 수 있는 설명과 바로 열 수 있는 링크를 넣은 Markdown 형식으로 바꿨다.

이제 수정 위치를 길게 설명하지 않아도 된다. 전달받은 사람은 링크를 열어 같은 화면과 같은 조건으로 이동하고, 수정 결과도 그 페이지에서 다시 확인한다. 도구 패널에는 해당 화면의 Figma 프레임도 연결했다. Storybook에서 구현 결과를 보다가 바로 기준 디자인을 열 수 있고, 화면이 실제 앱에 반영됐는지와 어느 라우트에서 쓰이는지도 함께 확인할 수 있다.
처음에는 Storybook을 화면을 보여주는 곳으로만 생각했다. 실제로 쓰다 보니 화면보다 그 주변 맥락을 함께 전달하는 일이 더 중요했다.
긴 문구와 빈 데이터도 화면 상태다
제품에서 문제가 생기는 조건은 성공과 실패 같은 비즈니스 상태만이 아니다. 문구가 길어지거나 데이터가 비었을 때도 화면은 쉽게 무너진다. 그래서 ‘레이아웃 스트레스’를 별도의 축으로 만들었다.
상품명이 네 줄로 길어지는 경우, 공지 제목이 한 줄을 넘는 경우, 노출할 공지가 없는 경우를 컨트롤에서 고를 수 있다. 예쁘게 맞춰둔 예시 데이터만 보여주는 대신 화면이 실제로 버텨야 할 조건을 꺼내놓았다.
간격처럼 숫자로 확인할 수 있는 값에는 자동 검사도 붙였다. Figma에서 추출한 헤더 높이, 좌우 여백, 카드 패딩, 보더 두께를 Storybook의 렌더링 결과와 대조한다. 요소가 프레임 밖으로 넘어가거나 화면 높이가 잘못 접히는 문제도 검사한다. 다만 색상과 그림자, 글자의 인상, 정렬이 자연스러운지는 여전히 사람이 Figma와 화면을 나란히 놓고 봐야 한다. 숫자로 잡히는 문제는 자동으로 막고 나머지는 사람이 보는 것이 지금으로서는 가장 현실적인 구분이라고 생각한다.
Storybook과 실제 앱이 갈라지지 않게 했다
Storybook을 협업 기준으로 쓰려면 실제 앱과 다른 화면을 보여줘서는 안 된다. 화면에 표시할 값을 스토리 안에서 다시 계산하지 않고 실제 라우트와 같은 변환 함수를 사용했다. Storybook에서만 쓰는 화면 컴포넌트도 따로 만들지 않았다. 앱의 구현은 바뀌었는데 Storybook만 옛 모습을 유지하는 일을 막기 위해서다.
컨트롤을 바꾸면 시나리오도 처음부터 다시 시작한다. 이전 조건에서 누적된 출석 횟수나 열린 팝업이 다음 조건에 남으면 실제로는 존재할 수 없는 화면이 생긴다. Figma 링크에는 화면마다 기준으로 삼은 프레임과 디자인 리비전을 기록했다. 링크가 엉뚱한 위치를 열거나 파일 첫 화면으로만 이동한다면 디자인 노드가 바뀌었는지 확인한다.
빨리 보여주는 일만큼 보여주는 화면을 믿을 수 있게 유지하는 데도 손이 갔다. 이 부분을 소홀히 하면 Storybook은 금방 참고용 샘플로 밀려난다.
Storybook에서 확인할 범위를 정했다
Storybook으로 실제 애플리케이션을 전부 대신하려고 하지는 않았다. 하나의 화면이 가질 수 있는 상태와 짧은 상호작용은 Storybook에서 확인하기 좋다. 반면 여러 화면을 오가는 내비게이션, 실제 API와 연결된 데이터 흐름, 인증과 권한, 운영 환경에서만 생기는 문제까지 담으려고 하면 Storybook도 무거워진다.
화면과 상태, 짧은 사용자 흐름은 Storybook에서 본다. 화면 사이의 이동과 실제 데이터 흐름은 개발 환경의 앱에서 확인한다. 보안과 데이터 정합성처럼 화면만 보고 판단할 수 없는 부분은 테스트와 CI가 맡는다. Storybook은 작은 범위의 결정을 빨리 내리는 데 사용하고, 그보다 넓은 제품 흐름은 앱에서 확인한다.

코드 리뷰만으로는 볼 수 없는 것
이 정도로 Storybook의 범위를 넓힐 수 있었던 데에는 AI의 발전도 큰 몫을 했다. 화면을 구현할 때마다 같은 상태를 Storybook에 다시 구성하고, 실제 앱과 어긋나지 않게 관리하려면 상당한 손이 든다. 기존 방식대로 사람이 모든 작업을 반복했다면 앱과 Storybook, 두 환경을 따로 관리하는 셈이 됐을 것이다.
지금은 AI가 기존 화면과 상태 변환 로직을 읽어 스토리의 골격을 만들고, 빠진 상태나 레이아웃의 경계 조건도 함께 찾는다. 이 반복 작업을 줄인 덕분에 Storybook을 한 번 만들고 방치하는 문서가 아니라 실제 제품과 함께 바뀌는 검토 환경으로 운영할 수 있었다.
물론 AI가 코드를 많이 작성한다고 두 환경이 저절로 일치하는 것은 아니다. 스토리 전용 화면을 복제하지 않고 실제 앱과 같은 상태 변환 함수를 사용한다는 원칙은 따로 세웠다. 구현량이 늘어날수록 사람이 모든 코드 변경을 같은 깊이로 따라가기 어려워지기 때문에, 무엇을 자동화에 맡기고 무엇을 사람이 직접 볼지도 다시 나눴다.
코드 규칙과 반복 검사는 테스트와 자동화에 맡길 수 있다. 반면 화면이 의도한 경험을 만드는지, 상태의 조합이 자연스러운지, 요구사항 자체가 맞는지는 사람이 판단해야 한다. Storybook에서는 작성한 코드를 설명하기보다 결과물을 놓고 이야기한다. 같은 화면을 열어 조건을 바꾸고 버튼을 눌러보면서 대화의 초점도 “이 코드를 왜 이렇게 작성했나요?”에서 “사용자가 이 상태를 만나면 무엇을 보게 되나요?”로 옮겨간다.
그래서 Storybook을 애자일 도구라고 부른다
Storybook을 도입한 뒤 개발 속도가 몇 퍼센트 빨라졌다고 말할 수는 없다. 과거의 피드백 왕복 횟수나 작업 시간을 같은 기준으로 측정하지 않았기 때문이다. 기억을 바탕으로 숫자를 만들어낼 생각도 없다.
대신 일하는 구조는 분명히 달라졌다. 예전에는 구현이 끝난 뒤 결과물을 비교했다. 지금은 구현 중간에 화면을 공유한다. 리뷰어는 정적인 스크린샷을 넘겨보는 대신 조건을 바꾸고 직접 눌러본다. 디자이너는 고칠 요소를 집어서 보내고 같은 Storybook 주소에서 수정 결과를 확인한다. 백엔드 개발자는 응답을 바꿔보며 API 계약이 화면에 미치는 영향을 미리 살펴본다.
내게 애자일은 회의 횟수나 티켓 크기의 문제가 아니다. 아직 고치기 쉬울 때 결과물을 보고 다음 결정을 내릴 수 있느냐에 가깝다. 그래서 Storybook을 컴포넌트 전시장으로만 쓰지 않기로 했다. 지금은 미완성 화면을 꺼내놓고 함께 눌러보는 곳으로 쓰고 있다.
READ NEXT
같은 주제의 글 더 보기
제 얼굴을 본뜬 SVG 프레젠터를 만들고, 프로그래머블 API와 TTS를 연동해 릴스 자동화 시스템에 넣었습니다. 팔과 손을 움직이던 첫 프로토타입부터 얼굴의 인상, 안경과 옷깃, 음성에 맞춘 동작을 다듬기까지 AI와 함께 겪은 시행착오를 정리했습니다.
Read EntrySpring·Kotlin 백엔드 구조를 다시 설계하며 UseCase, Domain, Repository의 책임과 상태 저장, 트랜잭션 경계를 정리한 기록입니다.
Read Entry
댓글 0
로그인 없이 익명으로 남길 수 있습니다.