스타트업에서 디자인 시스템을 구축해본 후기

content-logo

Table of Contents

본문

디자인 시스템은 제품 개발의 일관성과 효율성을 높이기 위한 중요한 도구이다. 그러나 이 도구가 성공적으로 그 역할을 하기 위해서는 많은 조건을 필요로 한다.

이 글에서는 약 7개월 동안의 디자인 시스템 구축 경험과 그 과정에서 겪은 실패에 대해 공유하고자 한다. 이 기간 동안 우리 팀은 이 시스템을 설계하고 실행하려 노력했으나, 여러 내외적 요인으로 인해 기대했던 결과를 얻지 못했다.

실패는 항상 교훈을 남긴다. 이 후기를 통해 우리 팀의 디자인 시스템 구축 도전 과정과 그로 인한 깨달음을 공유하고자 한다.

디자인 시스템이란?

디자인 시스템은 조직의 디자인과 개발 작업을 표준화하고 일관성을 유지하기 위한 일련의 가이드라인, 구성요소 및 패턴의 집약체이다. 디자인 시스템은 재사용 가능한 UI 컴포넌트, 디자인 토큰, 디자인 가이드, UX 라이팅 가이드, 사용법 문서 등을 포함할 수 있으며, 디자인과 개발 프로세스를 더욱 효율적이고 일관되게 가져갈 수 있다.

디자인 시스템 제작기

디자인 시스템의 필요성

2023년 6월에 우리 스쿼드에서는 조직의 생산성을 높이자는 취지로 디자인 시스템을 구축하기로 결정했다.

우리 조직이 겪고 있는 비효율성을 파악하기 위해 타 스쿼드의 프론트엔드 개발자 및 디자이너를 대상으로 유저 인터뷰를 진행했고 다음과 같은 문제점을 도출해내었다.

공통된 규칙의 부재

제품 개발 및 유지보수 시에 기준으로 삼을만한 공통 규칙이 부재하여 디자인과 개발 단에서 파편화가 발생했다.

폰트 패밀리나 primary 색상 조차 정의되어있지 않았기 때문에 같은 회사의 제품이라고 생각하기 힘들 정도였다.

여러 제품을 넘나드는 공통 컴포넌트가 없었기 때문에 거의 같은 모양의 ui 임에도 코드가 달랐다. 이렇다보니 컴포넌트 제작 시 재사용성에 대한 고민은 항상 경시되었다. 그 결과 비슷한 외형의 컴포넌트임에도 항상 새로 만들기 일쑤였다.

서로 다른 언어를 사용하는 제작자들

공통된 네이밍 규칙이 없어서 디자이너와 개발자들이 서로 다른 언어로 소통했다. 항상 지라, 피그마, 코드 에디터 등을 뒤지면서 서로가 쓰는 언어를 해독해야했다. 심지어 재직기간이 긴 동료가 중간에서 동시 통역사의 역할을 하는 경우도 있었다.

대표적인 케이스는 컴포넌트의 이름이었다.

사진의 컴포넌트는 일반적으로 BottomSheet 라는 이름을 갖는 컴포넌트이다.

img-bottom-sheet

디자인 시스템이 도입되기 전까지 이 컴포넌트는 다양한 이름으로 불리우고 있었다.

프론트엔드 챕터에서는 이 컴포넌트를 Pane 또는 팬이라고 부르고 있었다. 반면 디자인 챕터에서는 BottomSheet 또는 바텀 시트로 부르고 있었다. QA에서는 하단 출력 모달 이라고 부르는 경우도 있었다.

이처럼 각 챕터 별로 컴포넌트를 부르는 이름이 달라서 대화할 때나 Jira에 이슈를 등록할 때마다 네이밍을 고민하게되는 병목이 걸렸다.

디자인 시스템 제작 과정

유저 인터뷰와 레퍼런스 조사 등을 마친 후 23년 9월부터 디자인 시스템 작업을 본격적으로 시작했다.

디자인 시스템은 별도의 오픈소스 라이브러리를 사용하지 않고 직접 구현했다. 이유는 자유도 때문이었다. 오픈소스 라이브러리가 열어주는 범위 이외의 커스터마이징은 큰 공수가 들 것으로 보았고 이는 제약이 될 것으로 생각했다. 진짜 우리만의 것을 만드려면 직접 구현이 필요하다고 생각했다.

또한 지금은 소수의 인원으로 시작하지만 조직이 성장함에 따라 인재들이 합류하여 더 높은 수준으로 발전시킬 수 있을 것으로 예상했다.

우리는 직접 구현의 공수를 너무 과소평가했다.

2개의 시스템

회사의 제품은 크게 라이브 플레이어와 어드민으로 구성되어 있다. 두 제품은 성격이나 디자인이 너무 다르기 때문에 하나의 디자인 시스템으로 다루기는 어렵다고 판단했다. 따라서 라인의 디자인 시스템 사례를 참고하여 라이브 플레이어용 디자인 시스템과 어드민용 디자인 시스템을 각각 따로 운영하기로 결정했다.

디자인 토큰

제품의 제작자들이 공통된 언어를 사용할 수 있도록 디자인 토큰 체계를 도입했다. 토큰은 Global, Alias, Component 총 3개의 계층으로 이루어졌다. 디자인 시스템의 색상, 글꼴, 여백 부터 시작하여 컴포넌트의 색상, 테두리 등을 모두 토큰으로 구축했다.

img-design-token

(디자인 토큰을 활용한 의사소통)

코드 레벨에서는 디자인 토큰을 css 변수와 클래스네임으로 제작했다. 개발 시 토큰을 하드코딩하는 것을 최대한 줄이기 위해 변수 및 객체의 형태로 제공했다.

// heightSize.ts

export const variables = {
  sm: 'var(--mds-common-height-size-sm)',
  md: 'var(--mds-common-height-size-md)',
  lg: 'var(--mds-common-height-size-lg)',
} as const;

export const classNames = {
  sm: 'mds-common-height-size-sm',
  md: 'mds-common-height-size-md',
  lg: 'mds-common-height-size-lg',
} as const;

export const variants = {
  sm: { height: 'var(--mds-common-height-size-sm)' },
  md: { height: 'var(--mds-common-height-size-md)' },
  lg: { height: 'var(--mds-common-height-size-lg)' },
} as const;

// index.ts
export * as heightSize from '...';

일부 오픈소스 UI Kit에서 React 컴포넌트의 prop으로 토큰을 적용할 수 있는 사양에서 아이디어를 얻어, 디자인 시스템 컴포넌트의 prop에 디자인 토큰을 적용할 수 있도록 구현했다.

img-idea-from-chakra-ui

(Chakra UI에서 착안)

img-slack-message-1 img-slack-message-2

컴포넌트 인터페이스

작업자들이 컴포넌트 내부 컴포넌트로의 접근을 용이하게 하고, 컴포넌트의 책임을 분리하기 위해 합성 컴포넌트 패턴을 적극 활용했다.

비록 우리의 디자인 시스템은 자유도 보다 일관성을 위한 제약에 초점을 맞추고 있었지만, 디자인 시스템은 계속해서 발전하며 변해가기 때문에 규칙 자체가 바뀔 가능성도 있었다. 따라서 규칙 변경에 유연하게 대응하기 위해 합성 컴포넌트 패턴을 적용했다.

컴포넌트는 최대한 내부에서 상태를 갖지 않도록 했다. 내부의 상태가 많아질수록 관리 포인트가 늘어나며 오동작의 가능성이 높아질 수 있다고 판단했다. 따라서 최대한 단순하게 구현하며 React의 기본 jsx 동작을 최대한 존중했다.

스토리북

제품 담당 개발자들이 볼 수 있는 컴포넌트 사용 설명서가 필요했다. 컨플루언스 등의 문서도 좋지만 직접 컴포넌트를 조작해보며 육안으로 확인해볼 수 있는게 더 효율적이라고 판단하여 스토리북을 적극 활용했다.

스토리북의 각각의 페이지는 컴포넌트의 다양한 형태를 한 눈에 볼 수 있는 Overview 페이지와 controls 패널을 통해 조작해볼 수 있는 Playground 페이지로 구성했다. Playground 페이지에는 소스 코드가 포함되어있어 개발자들이 그대로 복사 붙여넣기 할 수 있도록 구성했다. 이를 통해 의도와는 다른 방식의 컴포넌트 합성을 최대한 방지하고자 했다.

img-storybook

버전 관리

디자인 시스템 라이브러리의 버전 관리를 위해 시맨틱 버전을 도입했다.

하위 버전과 호환되지 않는 대대적인 변화가 생길 경우 메이저 버전을, 하위 버전과 호환되면서 새로운 기능 또는 컴포넌트가 생길 경우 마이너 버전을, 그 외의 간단한 구조 변경 또는 에러 수정이 생길 경우 패치 버전을 올려 관리했다.

디자인 시스템은 GitLab 패키지 레지스트리에 배포했으며 changeset 을 도입하여 버전 관리를 편리하게 하고자 했다.

문서화 및 이슈 관리

스토리북에서 소스 코드와 결과물을 확인할 수 있지만, 그 외에 글로 작성된 문서가 필요하다고 판단했다. 문서는 컨플루언스에서 별도의 스페이스로 작성했으며 버전 변경 이력 (changelog)과 컴포넌트의 구현 목적 및 api 명세서 등을 작성했다.

회사의 모든 작업은 지라 이슈에 기반해서 이루어지고 있었다. 디자인 시스템의 이슈는 디자인 시스템이라는 에픽에서 각각의 시스템 별로 스토리를 구성했다. 그리고 작업 단위는 메이저 및 마이너 버전 단위로 구성하여 해당 버전이 증가할 때마다 이슈를 새로 발급했다. 패치 버전만을 위한 이슈는 발급하지 않았다.

디자인 시스템 운영

구축하는 것도 중요하지만 운영도 중요하다. 디자인 시스템을 아무리 잘 구축해도 사용자가 사용하지 않는다면 실패작에 불과하다. 구축도 중요하지만 이를 잘 세일즈하는 것도 중요하다. 무엇보다도 잘 발전시키며 운영하는 것이 제일 중요하다. 이러한 관점에서 우리 팀이 운영을 잘했는지를 돌이켜보면 부족했다고 생각한다.

img-slack-design-system-notification

(디자인 시스템의 초기 버전)

리더와 잠재적 사용자 설득

디자인 시스템을 처음 출시했을 때 잠재적 사용자의 반응은 크게 다음과 같았다.

  • 디자인 규칙과 공통 모듈이 가져올 효과를 기대하며 환영하는 입장
  • 규칙으로 인해 본인의 창의성이 제한받을 것을 우려하며 회의적인 입장
    • 또는 반대를 위한 반대를 하는 입장
  • 무관심

디자인 시스템 제작 당시 제품 별로 규칙이 너무 달라서 한 번에 통일하기가 어려웠다. 따라서 제품 하나하나씩 점진적으로 적용해나가는 방안을 선택했다.

아쉬웠던 점은 환영하는 입장의 제작자들이 담당하는 제품은 디자인 시스템 적용 대상에서 후순위에 있었다. 만약 그들의 우선순위가 높았다면 디자인 시스템을 전파하는데 든든한 아군이 되었을 것이라고 생각한다.

반면 우선순위가 높은 제품의 제작자들은 대부분 반대하는 입장이었다. 이들은 다음과 같은 점을 우려했다.

  • 디자인 시스템의 규칙만 따라야하는건지?
  • 디자인 시스템에서 제공되지 않는 컴포넌트가 필요하다면 어떻게 해야하는지?
  • 안그래도 바쁜데 디자인 시스템까지 신경써야하는지?

규칙이 없는 환경에서 작업하는게 익숙해져서 규칙이 도입되었을 때 본인들의 자유도가 제한받을 것을 우려하는 목소리가 컸다.

우리 팀은 이들을 설득하기 위해 사내 세션을 열어 발표를 진행했다. 세션에서는 다음과 같은 내용을 발표했다.

  • 디자인 시스템이 무엇인지
  • 디자인 시스템은 어떤 문제를 해결할 수 있는지
  • 디자인 시스템을 사용하기 위해 감수해야 할 점
    • 브랜드의 정체성과 제품의 일관성을 위해 어느정도 제약은 필요하다는 점
    • 디자인 시스템은 완성형이 아니라 제품과 같이 발전시켜나가야 한다는 점
  • 디자인 시스템에 없는 컴포넌트를 원할 경우 제품 제작팀에서 먼저 제작해서 사용하면 된다는 점
    • 그 후 담당자들끼리 논의하여 디자인 시스템에 반영할지 여부를 결정하자는 방향
    • 디자인 시스템이 제품 제작에 필요한 모든 컴포넌트를 제공해주지 않는다는 점
  • 라이브 코딩 시연
    • 디자인 시스템을 사용하여 UI를 구성하는 일련의 과정

img-session-notification

(세션 발표 공지)

img-session-ppt

(세션 발표 자료)

하지만 세션을 진행했음에도 불구하고 리더나 제작자들이 갖고 있는 우려는 쉽게 가라앉지 않았다. 이 상황에서는 시스템을 아무리 홍보해도 사용하지 않을 것이 뻔했다.

이 상황을 어떻게 풀어나갈지를 고민하던 중, 그렇다면 우리가 직접 디자인 시스템을 적용하고나서 보여주는게 어떻겠냐는 의견이 나왔다. 말로는 한계가 있다는 것이 이유였다.

규칙의 수립이 어떠한 변화를 가져오는지 직접 보여주자는 의견이었다. 또한 아직은 디자인 시스템에 불안정한 요소가 많을 것이기 때문에, 제공하기 전에 우리가 먼저 직접 사용하면서 개선하자는 의견도 많은 동의를 얻었다.

전사적으로 이 방향을 제시하여 동의를 얻었고 우리 팀은 제품에 직접 디자인 시스템을 적용했다.

라이브 플레이어에 먼저 시스템을 적용하며 디자인과 코드 상에서 파편화 되어있던 요소들을 교체했고 동시에 시스템도 같이 개선해나갔다.

라이브 플레이어는 컴포넌트의 수가 적었기 때문에 약 한 달이라는 짧은 기간 안에 적용이 완료되었으며 제작자들에게 시스템을 열 수 있게 되었다. 여전히 의문을 갖는 제작자가 있었지만 그래도 써보겠다는데까지는 동의를 얻어낼 수 있었다.

한계

어드민용 디자인 시스템을 적용하면서 점점 우리의 디자인 시스템의 한계가 드러나기 시작했다.

우리 회사는 규모가 그리 크지 않기 때문에 우리 팀이 디자인 시스템에만 집중하기는 어려웠다. 우리 팀은 곧 신제품의 어드민 개발에 참여했으며 어드민용 디자인 시스템을 적용해나갔다.

이 과정에서 여러가지의 한계점이 드러났다.

컴포넌트의 낮은 신뢰도

우리 팀의 프론트엔드 개발자는 나 혼자였다. 디자인 시스템의 컴포넌트 제작과 개선 및 유지보수, 제품 적용 및 제품 개발까지 모두 내 담당이었다.

나는 분명히 주니어로써의 한계를 갖고 있다. 짧은 시간 내에 높은 수준의 컴포넌트를 만들어내기란 어렵다. 제품 개발까지 병행했던 상황에서 디자인 시스템 개발에 온전히 집중하지 못했다.

이렇다보니 디자인 시스템 상의 컴포넌트에서도 크고 작은 오동작이 많이 발생했다. 유닛 테스트와 스토리북에서 이슈를 잡아냈더라도 제품 개발과 병행하며 이를 해결하는 일은 많은 리소스를 필요로 했다.

이로 인해 디자인 시스템 컴포넌트의 신뢰도가 갈수록 낮아졌다.

디자인 시스템은 모든 제품에게 단일 진실 공급원 (SSOT) 이 되어야 한다. 디자인 시스템이 흔들리면 제품도 흔들린다.

모든 것을 직접 제작한점

우리 디자인 시스템의 한계이자 컴포넌트의 신뢰도를 떨어트렸던 주된 원인은 바로 모든 것을 직접 구현했다는 점이라고 생각한다.

자체적으로 모든 것을 구현하려는 결정은 팀의 노력을 증가시킬 뿐만 아니라, 오류의 가능성을 높이고 결과적으로 전체 프로젝트의 신뢰성에 악영향을 미칠 수 있다.

우리 팀이 오픈소스 라이브러리에 기반하지 않고 디자인 시스템을 직접 만들기 시작한 이유는 자유도 때문이었다. 우리는 형태와 기능, 동작을 우리의 입맛대로 제작할 수 있다는 점을 크게 보았다. 반면 오픈소스 라이브러리는 그들이 제공해주는 컴포넌트와 API 만 사용해야하고, 그들이 열어주는 범위에서만 커스터마이징이 가능하다는 점을 제약으로 느꼈다.

그리고 지금은 소수의 인원으로 시작하지만 팀이 계속 성장하여 감당해나갈 수 있을 것으로 예상했다.

하지만 이는 큰 착오였다.

자유도가 높을수록 그만큼의 책임과 리소스를 필요로 한다.

자유도가 높다는 것은 다시 말하면 구현의 모든 것을 제작자가 전부 책임져야한다는 의미가 된다. 크고 작은 기능 모두를 직접 제작해야하며 확장성과 사용성 등에 대한 고민을 항상 해야한다. 충분한 고민 없이 제작해서 문제가 발생하는 상황까지도 전부 책임져야 한다.

반면 오픈소스 라이브러리를 사용할 경우 이미 검증된 컴포넌트와 기능을 사용할 수 있어 개발 시간과 비용을 절감할 수 있다.

오픈소스 라이브러리의 제약 사항은 분명 존재하지만, 그럼에도 웬만한 수준의 직접구현 보다는 훨씬 더 높은 수준의 신뢰도와 확장성을 보장한다. 오픈소스 라이브러리는 기여자 커뮤니티를 통해 계속 발전하므로 수준 이상의 유연성을 제공할 수 있다.

신뢰성 있는 오픈소스 라이브러리를 사용한다면, 팀은 기존의 잘 구축된 기능 위에 커스텀을 덧붙임으로써 적은 노력으로 큰 결과를 얻어낼 수 있다. 당연스레 팀은 디자인 시스템의 유지 관리와 확장에 더 집중할 수 있게되고 효율성을 높일 수 있다.

되돌아보면 우리는 오픈소스에 준하는 디자인 시스템을 만들려고 했던 것 같다.

우리는 오픈소스가 아니라 제품을 만드는 사람들이다.

동료들의 참여를 당연하게 기대한 점

디자인 시스템의 토대는 우리 팀이 만들지만 본격적으로 제품에 도입하는 시점에서는 다른 제품 제작자들의 적극적인 기여를 기대했다. 그래서 구성원 모두가 기여할 수 있고 다같이 발전시켜나갈 수 있는 디자인 시스템이 되기를 기대했다. 하지만 이는 어려운 일이었다.

제품 제작에 참여하고 있는 동료들은 그 일만으로도 바쁘다. 이들에게 디자인 시스템의 유지보수를 같이 담당하는 것은 단지 해야할 일이 하나 더 추가되는 것이며, 반가운 일이 아닐 수 있다.

모두가 디자인 시스템에 깊은 관심을 갖지는 않는다. 관심이 없는 사람도 있고 관심은 있지만 직접 참여하고싶지는 않은 사람도 있을 수 있다.

우리 팀은 이들이 자발적 • 비자발적으로 참여할 수 있는 환경을 조성하는 것에 더 신경써야 했다.

그 중에서도 결정권을 갖고 있는 리더들을 설득하지 못했던 것이 컸다.

대부분의 스타트업의 현실

리더들이 제기했던 의문의 핵심은 “꼭 필요한가요?”, “지금 우리가 그런거 할때인가요?” 이었다.

생존을 위해 당장 돈을 벌어야하는 스타트업에서 당장 돈이 되지 않는 작업은 부담스러울 수 밖에 없다. 지금 당장은 돈을 못벌어도 이후에 더 큰 돈을 벌어줄 수 있을 것 같다면 투자할 수 있을 것이다. 하지만 그런 확신이 들지 않는다면 리더들 입장에서는 눈엣가시일 수 밖에 없다. 우리에겐 디자인 시스템이 그러했다.

디자인 시스템에서 중시하는 가치에 공감대를 형성하지 못한다면 설득 비용은 커질 수 밖에 없다. 따라서 디자인 시스템에 대한 공감대를 형성하며 설득해나가는 과정이 꼭 필요하다.

대부분의 스타트업은 적은 인력이 많은 일을 담당한다. 회사의 규모가 작을수록 제품 개발에 투입될 확률이 높으며 디자인 시스템 등의 공통 모듈을 담당하는 플랫폼 팀을 마련하기 어려울 수 있다. 그렇다면 오픈소스를 도입하는 것이 좋은 선택지가 될 수 있다. 리소스가 한정된 상황에서 적은 노력으로 높은 신뢰도를 갖는 디자인 시스템을 구축할 수 있다.

맺으며

디자인 시스템에는 많은 조건이 필요하다.

  • 구성원들의 실력
  • 구성원들의 이해도
  • 구성원들의 자발적 • 비자발적 참여

이 중 하나라도 채우지 못할 경우 디자인 시스템에는 큰 위협이 될 수 있다. 구성원들의 동의 없이 혼자서만 떠들면 안된다.

회사의 규모가 작을수록 개개인에게 크게 의존할 수 밖에 없다. 따라서 인력 유출에 취약해질 수 밖에 없는 한계가 있다. 우리는 프론트 1명, 디자이너 1명이서 디자인 시스템을 구축했지만 디자이너 분께서 퇴사하시면서 곧바로 위기를 맞았다. 인력 순환이 잦은 스타트업일수록 디자인 시스템의 진입 장벽을 낮추기 위해 노력해야한다. 항상 잘 정리되어있어야하며 문서화가 잘 되어있어야한다. 인력 구조 변화에 항상 준비되어있어야 한다. 그렇지 않으면 디자인 시스템은 언제든지 무너질 수 있다.

마지막으로, 디자인 시스템을 제작하기 전에 지금 우리에게 디자인 시스템이 꼭 필요한가에 대한 충분한 고민이 필요하다. 디자인 시스템이 항상 최선의 선택지가 될 수는 없다. 규모가 크지 않거나 당장 눈앞의 생존이 급한 조직이라면 디자인 시스템은 오히려 과한 존재가 될 수 있다.