디자인 시스템 v2 도입기
디자인 시스템은 일관된 사용자 경험을 제공하고, 효율적인 디자인 및 제품 개발을 위해 디자인 원칙과 스타일 가이드, 구현 코드를 집약한 시스템입니다. 디자인팀과 개발팀의 공통 언어이자 지침이죠.
그래서 많은 회사에서 디자인 시스템을 구축해 관리하고 있습니다. 저희도 기존 디자인 시스템이 존재했습니다. 엄밀히 말하면 디자인 시스템이라고 불리던 코드는 존재했지만, 팀 전체가 공유하는 시스템으로서는 제대로 작동하지 않고 있었습니다.
이 글에서는 어떤 계기로 디자인 시스템 v2를 새로 만들게 되었는지 공유하려 합니다.
배경
저희 디자인 시스템은 모노레포의 공통 모듈로서 시작했습니다. 누군가의 적극적인 도입으로 시작된 것은 아니고, 디자이너와 FE 개발자 간 중복 컴포넌트에 대한 논의를 하며 자연스럽게 시작되었습니다.
첫 시작은 Button부터, 그 다음은 Input. 이런 식으로 DRY 원칙을 위반하던 요소들을 하나씩 공통화하는 작업에서 시작했습니다. 자연스럽게 다양한 요소들이 추가되었고, 색상과 타이포그래피 등이 추가되었습니다.
하지만 이렇게 만들어진 디자인 시스템은 서서히 우리에게 불편한 존재가 되어갔습니다. 우리가 공통으로 약속한 디자인 시스템에는 어떤 문제가 있었던 걸까요?
문제 인식
문제의 본질은 단순히 컴포넌트 품질이나 빌드 방식이 아니라, 디자인 시스템을 진정한 시스템으로 운영하지 못했다는 점이었습니다.
1. 합의되지 않은 언어
앞서 말씀드렸듯이 디자인 시스템은 디자인팀과 개발팀의 공통 언어입니다. 그런데 저희 디자인 시스템은 디자이너와 개발자 개인 간의 합의로 생성/관리되기 시작했습니다.
이는 나머지 구성원들이 이 언어를 만드는 과정에 제대로 참여하지 못했다는 뜻이었습니다. 물론 코드리뷰에서 어느 정도 검증을 할 수 있지만, 코드리뷰의 성격은 기술적으로 문제가 있는지를 탐색하는 과정에 가깝습니다.
의사소통에 참여하지 못한 구성원들은 새로운 요구사항이나 불편함이 생길 때마다 각자 수정을 요청했고, 디자인 시스템은 수시로 변경되었습니다.
그러다 보니 디자인 시스템은 점점 관리하기 어려운 구조가 되었습니다. 기존 속성은 누군가 필요해서 만들어두었다고 생각할 수밖에 없었고, 기존 속성은 제거되지 못한 채 필요한 기능이 있을 때마다 속성이 쉽게 추가되었습니다.
2. 수많은 디자인 시스템 분기
저희 프로젝트는 모노레포로만 관리되지 않았습니다. SI/용역 프로젝트가 대다수를 이루었고, 이는 계획적으로 별도 독립 레포지토리로 생성해서 관리되었습니다.
하지만 디자인 시스템은 모노레포에 있었죠. 결국 별도 레포지토리에서 작업하는 개발자들은 디자인 시스템 코드를 복사/붙여넣기 해서 별도 레포에 다시 생성했습니다.
여기서 끝나면 다행이겠지만, 불행하게도 별도 레포지토리에서 작업하면서 디자인 시스템은 계속 수정되었습니다. 프로젝트가 생길 때마다 디자인 시스템의 분기가 생겨났습니다.
어느 순간 어떤 디자이너 혹은 개발자가 이렇게 묻습니다.
"이거 저번에 디자인 시스템에 추가한 건데요?"
아마 수많은 프로젝트 어딘가에서는 작업되었던 기능이겠지만, 어쨌든 모노레포 내 본 디자인 시스템에는 전혀 반영되지 못하고 있었던 것이죠. 이렇게 수많은 분기가 발생하면서 프로젝트별로 디자인 시스템을 별도 관리하는 상황까지 이르렀습니다.
결국 디자인 시스템을 공유 자산이 아닌 프로젝트별 사본으로 취급하게 되었고, 이는 시스템의 존재 이유 자체를 흔들게 되었습니다.
3. 심각한 수정 사이드 이펙트
디자인 시스템이 모노레포로 관리되면서 생긴 또 다른 문제는 디자인 시스템의 수정이 모든 프로젝트에 영향을 미친다는 것이었습니다.
내가 관리하던 프로젝트는 가만히 있었는데, 다음번 배포하려고 하니 디자인 시스템에서 타입 오류가 납니다. 디자인 시스템이 수정된 것이죠.
그럼 그때 개발자는 디자인 시스템에 맞춰 프로젝트를 업데이트해야 합니다. 단순히 개발자가 작업을 완료하면 끝나는 게 아니라, 디자이너도 프로젝트 전반적으로 영향 범위를 확인해야 합니다. 예상치 못한 작업이 발생하게 되어 시간 소요가 늘어납니다.
4. React 버전 충돌
기술적으로 가장 골치 아팠던 문제 중 하나는 React 버전 충돌이었습니다. 디자인 시스템은 모노레포에 있었고 Rollup으로 빌드해 사용하고 있었습니다. React는 peerDependencies로 설정되어 있어 디자인 시스템을 사용하는 프로젝트의 버전을 따르게 되어 있었죠.
하지만 디자인 시스템 프로젝트에도 개발을 위해 node_modules 내 React가 설치되어 있었고, 프로젝트에서 별도 처리를 하지 않으면 디자인 시스템 내 node_modules의 React를 바라보게 되었습니다.
매번 디자인 시스템 빌드 후 디자인 시스템의 node_modules를 제거하거나, 프로젝트에서 alias를 설정해 react는 항상 프로젝트의 node_modules/react를 바라보도록 처리해줘야 했습니다.
이렇게 점점 많은 문제점들이 쌓여가고 있었습니다.
도입 과정
마침 2024년 중순 사내 조직개편이 진행되면서 목적 조직을 기능 조직으로 개편하게 되었고, 이 과정에서 FE팀 리드를 맡게 되었습니다. 이때 가장 먼저 디자인 시스템의 개선을 생각하고 움직였습니다. 여러 개의 새 프로젝트가 예정되어 있는 상황에서 디자인 시스템의 분기를 더 늘릴 수는 없었기 때문입니다. 이 과정에서 가장 중요하게 잡았던 기준은 두 가지였습니다.
- 빠르게 배포 가능한 최소 단위의 시스템
- 합의와 참여가 자연스럽게 발생하는 구조
1. 준비 단계
우선 디자인 팀과 협력해 기존 디자인 시스템을 취합했습니다. 어떤 컴포넌트에 어떤 속성들이 사용되고 있었고, 어떤 의도로 사용되고 있었는지 정리했습니다. 이 과정에서 많은 컴포넌트를 과감하게 제거했습니다. 정책이 제대로 정해져 있지 않거나 특정 프로젝트를 위해 제작되어서 디자인 시스템에 들어오기에는 성숙하지 않은 컴포넌트들을 모두 제거했습니다.
속성들도 모두 걸러내 중복된 속성을 합치고, 특정 프로젝트를 위한 속성은 제거한 뒤 확장 가능성을 열어두는 방향으로 진행했습니다. 마지막으로 일부 프로젝트에 적용되어 있던 다크모드 지원 여부를 고려하며, 어떤 컴포넌트를 v2 초기 버전에 포함할지 결정했습니다. 이 과정은 디자인팀과 일주일간 집중적으로 논의하며 빠르게 마무리했습니다.
이 과정에서 결정된 것들은 다음과 같습니다.
- 기존 디자인 시스템에서 30개가량 되었던 컴포넌트를 10여 개로 줄이기로 결정했습니다. 현재 중요한 것은 디자인 시스템이라는 개념의 정상화라고 생각했고, 이를 위해서는 커버 범위를 넓히는 것보다 기본 시스템의 빠른 배포가 훨씬 중요하다고 생각했습니다.
- 디자인 시스템 내에서 다크모드를 지원하도록 설계했습니다. 다크모드는 매번 고려하기에는 디자인팀, 개발팀 모두 비용이 많이 드는 작업이기 때문에 시스템화의 효율이 높다고 생각했습니다.
- 디자인 시스템은 패키지로 배포하기로 결정했습니다. 기존 모노레포 구조의 문제점을 해결하기 위함입니다.
- Storybook을 배포해 현재 디자인 시스템의 상태를 누구나 웹에서 확인할 수 있도록 결정했습니다.
2. 구현 단계
우선 자리를 디자인 팀장 옆으로 옮겨 서로 물리적으로 가까운 위치에서 하나의 시스템 완성을 위해 노력했습니다. 디자인 팀장은 컴포넌트별로 피그마 작업 완료 후 디자이너 & 개발자 리뷰를 거쳤고, 리뷰를 거친 컴포넌트들은 옆자리에서 제가 빠르게 제작해서 PR 리뷰를 통해 개발자 검증을 거쳤습니다.
다크모드 색상은 CSS Variables를 사용해서 특정 플래그에 의해 프로젝트 전체에 영향을 미치도록 구현했습니다. 이렇게 2주간의 집중 개발 과정을 거쳐 디자인 시스템 v2의 초안을 완성했습니다.
3. 배포 및 적용
완성된 프로젝트는 Vercel을 사용해 Storybook을 배포하고, GitHub Actions로 워크플로우를 작성해 Private GitHub Packages로 publish했습니다. 팀 내 환경변수 관리 시스템인 doppler로 github token을 관리하고, 프로젝트에서 해당 패키지에 접근할 수 있게 처리했습니다.
배포 후에는 버저닝 정책을 바로 결정해 디자인팀과 개발팀에 공유했습니다.
- minor 버전: 양자 합의에 의해 해결되어야 하는 수정(디자인 수정, 기능 수정, 기능 추가 등)
- patch 버전: 개발자의 통보에 의해 해결될 수 있는 수정(버그 수정, 디자인 불일치 수정)
- major 버전: 이후 호환성을 완전히 배제하고 새로운 디자인 시스템을 위해 남겨둠
이후 새로운 프로젝트에서는 디자인 시스템 사용을 강제하고, 디자인 변경이 필요한 경우 디자인 시스템 수정을 진행하는 방향으로 워크플로우를 만들었습니다. 디자인 시스템 수정을 위해서는 minor 버전을 올려야 하고, 이를 위해서는 디자인팀 & 개발팀 전체 합의가 필요하므로 자연스럽게 전원이 변경사항을 팔로업할 수 있게 되었습니다.
결과
바로 다음 프로젝트부터 성공적으로 디자인 시스템을 사용해서 개발을 진행할 수 있게 되었습니다. 실제로 제가 진행한 다음 프로젝트는 디자인 시스템 v2 작업을 위해 3주가량 딜레이된 상황이었습니다. 하지만 디자인 시스템을 사용한 개발로 이 딜레이를 상쇄했으며, 이후 디자인과 개발에서는 훨씬 빠른 속도로 일관된 경험을 제공할 수 있게 되었습니다.
| 구분 | 디자인 시스템 v1 (AS-IS) | 디자인 시스템 v2 (TO-BE) |
|---|---|---|
| 관리 형태 | 모노레포 내 내부 모듈 | 독립 레포지토리 & 패키지화 |
| 배포 방식 | 심볼릭 링크 / 복사-붙여넣기 | GitHub Packages (NPM) |
| 컴포넌트 수 | 30개+ (파편화된 기능) | 10여 개 (핵심 공통 요소) |
| 업데이트 | 실시간 강제 반영 (사이드 이펙트) | 버전 선택적 업데이트 (안정성) |
| 의사결정 | 개인 간의 구두 합의 | 전사적 리뷰 & 버전 정책 준수 |
패키지로 배포되어 디자인 시스템이 업데이트되어도 기존 프로젝트들은 영향을 받지 않게 되었습니다. 버전을 올리지 않으면 변경사항이 적용되지 않으니까요. 또한 프로젝트 진행 중 새로운 컴포넌트가 필요해지면, 그것을 디자인 시스템에 추가해야 할지 성숙한 논의를 거칠 수 있게 되었습니다.
이후 다른 디자이너와 개발자들도 신규 프로젝트는 디자인 시스템 v2를 도입해서 개발하게 되었고, 초기 디자인과 개발 속도가 상당히 향상되었습니다. 기존 프로젝트들 중 관리되고 있던 프로젝트들도 서서히 디자인 시스템 v2로 전환되며, 이는 다시 디자인 시스템 v2의 발전으로 이어졌습니다.
마무리
돌이켜보면 기존 디자인 시스템의 가장 큰 문제는 기술적인 부분이 아니었습니다. 팀 전체가 함께 만들고 합의한 시스템이 아니었다는 점, 그래서 누구도 주인의식을 갖기 어려웠다는 점이 근본적인 원인이었습니다.
v2를 만들면서 가장 신경 쓴 부분도 바로 이 지점이었습니다. 컴포넌트 수를 과감히 줄이고, 모든 변경에 전원 합의를 요구하는 프로세스를 도입한 것은 단순히 품질 관리를 위해서가 아니라 모두가 참여하고 합의하는 시스템을 만들기 위함이었습니다.
물론 아직 갈 길이 멉니다. 10여 개의 컴포넌트는 최소한의 출발점일 뿐이고, 앞으로 프로젝트를 진행하며 컴포넌트를 추가하고 정책을 다듬어가야 합니다. 하지만 이제는 그 과정이 혼란이 아닌 구성원 전원의 성장이 될 수 있는 기반을 갖추었다고 생각합니다.
디자인 시스템을 새로 구축하거나 개선하려는 분들께 하나 말씀드리자면, 완벽한 시스템을 한 번에 만들려 하기보다 작게 시작하되 제대로 된 프로세스를 먼저 갖추는 것을 권해드립니다. 결국 디자인 시스템은 코드가 아니라 팀의 약속이니까요.