디자인 시스템을 처음 맡은 리드의 회고

좌충우돌, 잘 모르는 자리에서 듣고, 묻고, 함께 기준을 만들어간 이야기
처음 디자인 시스템 회의에 들어갔을 때, 나는 이미 결정된 내용을 제대로 이해하지 못한 채 넘어간 적이 있다. 다음 회의에서 잘못된 전제를 바탕으로 이야기했고, 끝난 논의를 다시 되돌렸다.
돌이켜보면 초반에는 회의에 도움이 되기보다 흐름을 방해한 순간도 있었다.
프론트엔드 팀 리드가 되고 처음 맡은 일 중 하나가 디자인 시스템 구축이었다. 공통 컴포넌트를 만들고 토큰을 관리한 경험은 있었지만, 디자인팀·네이티브팀·웹팀이 함께 하나의 시스템을 설계하고 운영하는 일은 처음이었다.
솔직히 당시에는 디자인 시스템을 지금만큼 중요하게 생각하지도 않았다. 새로운 기능을 만드는 일에 비하면 제품에 미치는 영향이 간접적으로 느껴졌다. 공통 컴포넌트를 잘 만들어두면 개발이 조금 편해지는 정도로 이해했다.
그런 상태로 여러 팀의 리드와 담당자가 모인 회의에 들어갔다. 나를 제외한 참석자들은 각자의 영역에서 비슷한 문제를 오래 다뤄온 사람들이었다.
마음이 조급했다. 리드로 회의에 들어왔는데 잘 아는 것은 없고, 그렇다고 가만히 앉아만 있어도 되는지 알 수 없었다. 뭔가 해야 할 것 같은데 무엇을 해야 하는지는 보이지 않는 기분이었다.

머리를 믿지 않게 된 계기
이미 결정한 내용을 놓쳐 회의를 되돌린 뒤로는 회의에 들어가는 방식부터 바꿨다.
그전까지는 대화의 흐름을 따라가며 중요한 내용은 기억할 수 있다고 생각했다. 하지만 익숙하지 않은 영역에서 여러 직군의 관점이 빠르게 오가는 회의는 머리만 믿고 따라갈 수 있는 자리가 아니었다.
그때부터 회의에 들어가면 반드시 메모했다. 정식 회의록이 아니어도 괜찮았다. 무엇을 결정했는지, 아직 결정하지 못한 것은 무엇인지, 내가 이해하지 못한 표현은 무엇인지를 나만의 방식으로 적었다.

모르는 내용을 그대로 넘기는 일도 줄이려고 했다. 회의 중에 바로 묻지 못했다면 끝난 뒤라도 잘 아는 동료를 찾아갔다. 내가 이해한 내용이 맞는지 확인하고, 다음 회의 전에 필요한 맥락을 다시 살펴봤다.
리드라는 이유로 뭐라도 빨리 말해야 한다는 생각도 조금씩 내려놓았다. 조급함을 없앨 수는 없었지만, 그 감정에 매달리기보다 지금 할 수 있는 일을 찾는 편이 나았다.
처음 얼마간은 많이 들었다. 각 팀이 무엇 때문에 답답해하는지, 같은 화면과 상태를 두고도 왜 서로 다른 이야기를 하는지 관찰했다. 그러면서 웹팀을 대표해 이 자리에 들어온 내가 무엇을 알아야 하고, 어떤 정보를 가져와야 하는지를 생각했다.

앞으로 나가지 못하는 프로젝트
처음 세운 계획은 비교적 단순했다.
디자이너들이 공통 컴포넌트의 스펙을 정리하면 개발팀과 함께 검토한다. 검토가 끝나면 컴포넌트를 구현하고, 기존 화면을 새 컴포넌트로 옮긴다. 공통화할 컴포넌트 목록도 이미 정리되어 있었다.
하지만 마이그레이션을 준비하면서 중요한 전제가 무너졌다. 어떤 화면과 상태를 옮길지 판단하려면 현재 제품의 모습이 Figma에 정리되어 있어야 했는데, 실제 Figma는 여러 파일에 파편화되어 있었고 최신 상태를 파악하기 어려웠다.
결국 이미 구현된 화면을 플로우 단위로 다시 정리하는 작업부터 시작했다.
이 과정에서 실제 서비스에 필요한 상태가 충분히 표현되지 않은 경우가 계속 발견됐다. 정상 상태는 있지만 에러 상태가 없거나, 텍스트가 길어지는 경우, 데이터가 없는 경우, 로딩과 비활성화 상태가 빠져 있었다.
영역마다 시작 조건도 달랐다. 웹팀이 맡은 영역은 담당 디자이너와 개발팀이 이미 도메인 맥락을 공유하고 있어 누락을 발견해도 비교적 빠르게 보완할 수 있었다.
반면 네이티브팀이 맡은 회원가입 퍼널은 규칙과 예외가 훨씬 많았다. 이를 정리하던 담당자에게도 익숙하지 않은 도메인이었다. 검토하고 보완을 요청한 뒤 다시 확인하면 다른 누락이 발견됐다. 디자인 시스템 회의에서는 기준을 정하기보다 빠진 상태를 다시 찾는 데 시간이 쓰였고, 퍼널 하나를 정리하는 데 두 달 가까이 필요했다.
처음에는 흔한 협업 문제라고 생각했다. 조금 더 자주 이야기하고 필요한 내용을 구체적으로 요청하면 해결할 수 있을 것 같았다.
하지만 네이티브팀은 다르게 판단했다. 그들은 이미 오랫동안 비슷한 상황을 반복해서 겪고 있었다. 실무자끼리 한 번 더 이야기하는 것만으로는 달라지지 않는다고 보았고, 결국 상황을 테크 조직장에게 알렸다. 이슈는 경영진이 인지하는 단계까지 올라갔다.
나는 그 장면이 조금 낯설었다. 가능하면 당사자끼리 온화하게 이야기하며 해결하고 싶어 하는 내 방식과는 달랐다. 네이티브팀 사람들과 따로 이야기할 기회가 생겼을 때 솔직하게 물었다.
“이게 에스컬레이션까지 해야 할 일이었을까요? 직접 이야기하면서 풀 수도 있는 문제 같았는데요.”
반응은 별로 좋지 않았다. 그들은 오히려 내가 왜 그렇게 생각하는지 이해하기 어렵다는 쪽에 가까웠다.
같은 누락, 다른 비용
당시에는 그 반응이 의아했다. 시간이 지나 다시 생각해보니 나는 상황을 내가 서 있던 위치에서만 판단하고 있었다.
웹에서는 상태 하나가 빠져도 디자이너와 다시 이야기한 뒤 비교적 빠르게 수정할 수 있었다. 문제가 발견되면 다시 배포할 수 있었고, 급한 상황에서는 긴급 배포도 가능했다.
네이티브팀이 부담하는 비용은 달랐다. 복잡한 회원가입 퍼널에서 상태 하나가 빠진 채 앱이 배포되면 스토어 심사와 배포 주기 때문에 곧바로 수정하기 어려웠다.
내가 “하나 빠졌네. 다시 이야기하면 되겠다”고 생각한 일이 누군가에게는 출시 일정 전체를 흔드는 일이었다.
같은 누락을 보고 있어도 각 팀이 지불하는 비용은 같지 않았다. 나는 그 차이를 충분히 확인하지 않은 채 에스컬레이션이 과한지부터 판단했다. 내게 몇 번의 추가 대화로 해결할 수 있는 일이었다고 해서, 다른 팀에도 같은 무게의 일이라고 생각한 것이다.
디자인팀이 놓인 조건도 뒤늦게 보이기 시작했다.
당시 디자인 조직에는 여러 제품팀의 요구를 조율하고 디자인 시스템의 방향과 우선순위를 책임질 역할이 공석이었다. 디자이너들은 새로운 기능의 출시 일정을 맞추면서 동시에 기존 디자인 자산도 정리해야 했다. 디자인 시스템은 중요했지만 늘 더 급한 일 뒤로 밀릴 수밖에 없었다.
파편화된 Figma는 개발팀의 오래된 코드베이스와 비슷한 상태였다. 비슷한 컴포넌트가 여러 파일에 존재했고, 어느 것이 현재 사용하는 버전인지 바로 판단하기 어려웠다. 하나를 수정했을 때 어디에 영향을 주는지도 쉽게 알 수 없었다.
그런 환경에서 “왜 엣지 케이스까지 챙기지 않았느냐”고 묻는 것은 상황의 절반만 보는 일이었다. 누군가가 꼼꼼하지 않아서 빠뜨린 것이 아니라, 필요한 상태를 빠짐없이 찾고 유지하기 어려운 구조 속에서 일하고 있었다.
그제야 네이티브팀의 에스컬레이션도 다르게 보였다.
당시에는 리더 역할의 공백, 여러 팀의 우선순위, 개발 일정 조정처럼 실무자들에게 결정 권한이 없는 사안들이 얽혀 있었다. 실무자끼리 아무리 온화하게 이야기해도 그 권한 자체가 생기지는 않는다.
네이티브팀은 누군가를 공격하기 위해 사람을 위로 올린 것이 아니었다. 해결에 필요한 권한과 자원을 확보하기 위해 문제를 적절한 위치에 알린 것이었다.
지금 같은 상황이라면 에스컬레이션까지 해야 했느냐고 판단하기보다, 실무자끼리 해결하기 어렵다고 느낀 지점이 어디였는지 먼저 물을 것 같다. 그들이 이미 어떤 대화를 반복했고, 그동안 어떤 비용을 지불했는지를 먼저 들을 것이다.
현재를 먼저 펼쳐놓기
이때 네이티브팀 리드가 Overall이라는 작업을 제안했다. 현재 서비스의 화면과 상태, 정책을 한곳에 펼쳐놓고 모두가 같은 현황을 보자는 제안이었다.
그동안 Figma 정리는 디자인팀의 영역으로 여겨졌다. 하지만 당시 상황은 어느 한 팀이 혼자 해결할 수 있는 범위를 넘어가 있었다. 디자인팀에 보완을 요청하는 일을 반복하기보다 실제 제품을 가장 잘 알고 있는 개발팀도 함께 현재 상태를 확인해야 했다.
나도 이 방향에 찬성했다.

Overall의 방향을 제안한 것은 네이티브팀 리드였지만, 웹팀의 범위를 정하고 실행 계획으로 옮기는 것은 내 역할이었다. 우리 팀에도 기능 개발 일정이 있었기 때문에 개발자를 현황 정리에 투입하는 일은 당장에는 비효율적으로 보일 수 있었다.
하지만 이미 우리는 디자인을 받고, 개발을 시작하고, 누락을 발견하고, 다시 질문하고, 디자인과 구현을 수정하는 비용을 반복해서 내고 있었다.
선택지는 기능 개발과 문서화 중 하나를 고르는 것이 아니었다. 지금 일정의 일부를 투자해 기준을 만들 것인지, 앞으로 만드는 기능마다 같은 재작업 비용을 계속 낼 것인지에 가까웠다.
반복되는 문제가 많거나 디자인 시스템 적용 가능성이 높은 영역부터 범위를 정했다. 팀원들은 각자 가장 잘 아는 도메인의 화면과 상태를 맡았다. 나는 전체 분류 체계를 맞추고, 영역마다 다르게 정리된 사례를 비교하며 공통으로 다뤄야 할 상태를 모았다. 동시에 한 영역은 직접 조사했다. 결과만 취합해서는 실제로 무엇이 어려운지 놓칠 것 같았다.
방식은 역추적이었다. Figma가 아니라 실제 서비스에 구현된 코드를 출발점으로 삼았다. 현재 화면에는 어떤 상태가 있는지, 어떤 정책으로 움직이는지, 어떤 예외 처리가 들어가 있는지를 하나씩 확인했다.
물론 현재 코드가 항상 옳은 것은 아니었다. 오래된 구현도 있었고 플랫폼이나 화면에 따라 동작이 갈라진 경우도 있었다. 그래서 코드를 정답으로 삼지는 않았다. 지금 우리가 실제로 어떻게 동작하고 있는지 확인하기 위한 근거로 사용했다.
서로 다른 구현이 발견되면 정책상 의도된 차이인지, 플랫폼 환경 때문에 필요한 차이인지, 역사적으로 갈라진 레거시인지 구분했다. 레거시라면 디자인과 개발 담당자가 어떤 동작을 표준으로 가져갈지 다시 논의했다.
다른 팀이 제안한 방향에 동의했다면 웹팀의 결과도 약속한 시점에 나와야 다음 단계가 움직일 수 있었다. 진행 상황과 남은 범위를 계속 확인했고, 웹팀이 맡은 결과를 계획한 기한 안에 가져갔다.
그렇게 화면·상태·정책을 모은 Overall 문서가 만들어졌다.
경청하면서 웹팀의 몫을 찾기
여러 팀이 함께 방향을 정하는 자리에서는 경험 많은 동료들의 판단을 먼저 들었다. 그렇다고 웹팀이 구현 단계에서 전달받은 내용을 옮기는 역할에만 머물 수는 없었다.
내가 가져갈 수 있는 것은 웹의 실제 구현 상황이었다.
디자인에서 제안한 구조가 웹에서도 구현 가능한지, 기존 화면은 어떻게 동작하고 있는지, 공통 컴포넌트로 옮겼을 때 어떤 위험이 생길 수 있는지를 확인했다.
디자인에서는 하나의 상태처럼 보여도 웹에서는 포커스와 키보드 조작, 마우스를 올렸을 때의 상태까지 고려해야 했다. 터치 환경을 중심으로 보는 앱팀에서는 중요하지 않을 수 있는 hover도 웹팀에서는 별도의 상태로 제안해야 했다.
웹팀에서는 Storybook도 구축했다. 회의에서 정적인 화면만 보고 이야기하는 대신 컴포넌트의 상태와 조합을 직접 확인할 수 있게 만들었다. 긴 텍스트, 로딩, 비활성화, 에러처럼 실제 제품에서 나타날 수 있는 경우를 펼쳐놓고 함께 논의했다.
나는 디자인과 네이티브의 방향을 대신 결정하려고 하기보다, 그 결정이 웹에 들어왔을 때 필요한 조건을 찾으려고 했다.
구현할 수 있는가. 기존 동작과 충돌하지 않는가. 웹에서만 필요한 상호작용이 빠지지는 않았는가. 상태 조합이 늘어났을 때도 컴포넌트의 구조가 버틸 수 있는가.
내가 잘 아는 영역에서는 구체적인 근거를 가져가고, 잘 모르는 영역에서는 필요한 일을 지원하려 했다.

모르면 찾아가서 물었다
팀 안에서 구성원과 일정을 챙기는 역할에는 조금씩 익숙해지고 있었다. 하지만 팀 밖에서 웹팀을 대표하고 다른 팀의 조건을 이해하는 일은 또 다른 문제였다.
네이티브팀과 웹팀이 같은 컴포넌트를 만들 때 무엇을 함께 맞춰야 하고 무엇을 플랫폼별로 남겨야 하는지 고민하다가, 네이티브팀 동료의 자리로 직접 찾아간 적이 있다.
내가 지금 무엇을 고민하고 있고 어떤 기준을 알아야 할지 잘 모르겠다고 솔직하게 털어놓았다. 완성된 답을 들고 가서 검토를 요청한 것이 아니라, 아직 정리되지 않은 고민부터 꺼냈다.
그렇게 접근했을 때 대화가 잘 풀렸다.
동료들은 네이티브 환경에서 중요하게 보는 기준과 내가 미처 생각하지 못한 제약을 알려줬다. 나는 그 내용을 웹의 조건과 비교하며 공통으로 맞출 것과 다르게 가져갈 것을 정리했다.
리드라고 해서 모든 답을 가지고 회의에 들어갈 필요는 없었다. 하지만 무엇을 모르는지 확인하고, 누구에게 물어야 하는지 찾고, 들은 내용을 우리 팀의 실행으로 연결하는 일은 내가 해야 했다.
List 컴포넌트를 설계하며 느낀 재미
공통 컴포넌트 설계가 본격적으로 시작됐을 때는 List 컴포넌트의 첫 설계를 내가 만들어 갔다.
List는 단순히 텍스트와 아이콘을 나열하는 컴포넌트가 아니었다. 왼쪽과 가운데, 오른쪽, 하단에 무엇이 들어가는지에 따라 정보의 의미와 상호작용이 달라졌다. 행 전체가 이동을 담당하는 경우가 있었고, 별도의 조작 요소가 함께 있는 경우도 있었다.
나는 실제 서비스에서 List가 사용되는 화면을 모았다. 어떤 정보가 어느 위치에 들어가는지, 어떤 상태와 조합이 존재하는지 확인했다. 웹에서 추가로 고려해야 하는 키보드 접근성과 포커스, hover 상태도 설계 논의에 가져갔다.
가능한 조합을 모두 자유롭게 허용하는 것이 정말 유연한 설계인지도 고민했다. 제품에서 허용한 조합과 피해야 할 조합을 구분하지 않으면 사용하는 개발자마다 List를 다르게 해석할 수 있었다. 구현하기 어렵거나 상호작용이 충돌할 가능성도 설계 단계에서 먼저 이야기하려고 했다.
그 내용을 설계 문서로 정리해 회의에 가져갔다.
문서를 두고 두세 시간가량 깊은 토론이 이어졌다. 시니어 네이티브 개발자들과 디자이너들이 각자의 관점에서 사례를 짚고 질문을 던졌다. 나도 왜 그렇게 나눴는지 설명하고, 반례가 나오면 다시 구조를 살펴봤다.
그 시간이 즐거웠다.
처음 맡은 영역을 성실하게 파고들었다는 점을 동료들이 알아봐 준 것도 기분이 좋았다. 무엇보다 하나의 컴포넌트를 두고 디자인과 웹, 네이티브의 사람들이 오랫동안 생각을 주고받는 과정 자체가 재미있었다.
논의가 끝난 뒤에는 공통 컴포넌트를 설계할 때 함께 확인할 체크리스트와 템플릿도 만들었다. 처음부터 내가 알고 있던 기준을 정리한 것은 아니었다. 동료들에게 묻고, 논의에서 충돌하고, 서로 다른 환경을 비교하면서 알게 된 내용을 다음 작업에서도 사용할 수 있도록 남긴 것이었다.
좋은 동료들과 일할 수 있어서 좋았다. 내가 경험하지 못한 상황을 먼저 겪은 사람들이 있었고, 잘 모르는 것을 물었을 때 시간을 내어 함께 고민해주는 사람들도 있었다. 나 역시 웹팀에서 발견한 근거와 구현상의 고민을 가져가며 그 대화에 참여할 수 있었다.
처음에는 디자인 시스템을 공통 컴포넌트를 만들어 개발을 조금 편하게 하는 일로 생각했다. 하지만 이 경험을 지나며 생각이 달라졌다.
같은 화면을 디자인과 웹, 네이티브가 서로 다르게 보는 이유를 이해하고, 실제 제품에서 근거를 찾고, 그 차이를 컴포넌트와 문서, 협업 방식으로 옮기는 일도 디자인 시스템을 만드는 과정이었다. 그리고 그 안에는 내가 좋아하는 종류의 프론트엔드 고민이 많이 들어 있었다.
이후 내 관심은 사람이 합의한 디자인 시스템의 기준을 AI도 이해하고 활용할 수 있게 만들려면 무엇이 필요한가라는 질문으로 이어졌다.
List 컴포넌트를 프론트엔드에서 어떻게 설계했는지, 웹팀의 Storybook과 문서를 어떻게 발전시켰는지, AI가 이해하기 쉬운 디자인 시스템을 만들기 위해 어떤 시도를 했는지는 다음 글에서 조금 더 기술적으로 다뤄보려 한다.
디자인 시스템을 처음 맡았던 시간은 멋진 동료들에게 배우면서 다른 팀과 일하는 법을 익히고, 프론트엔드 개발에서 내가 좋아하는 일이 무엇인지 조금 더 분명히 알게 된 시간이었다.
