Jeonghwan's Blog
주니어 개발자의 우여곡절 디자인 시스템 개발기

주니어 개발자의 우여곡절 디자인 시스템 개발기

디자인 시스템, 다들 한 번쯤은 들어보셨나요?

처음에 저는 "디자인 시스템이 그냥 공통 UI 컴포넌트를 잘 만들어두는 것 아닌가?"라고 단순하게 생각했어요. 하지만 실제로 직접 만들어보니 예상보다 훨씬 복잡했고, 고려해야 할 요소도 많았고, 예상치 못한 우여곡절이 많았어요.

이번 글에서는 제가 "2024 SSAFYnale 기술 컨퍼런스"에서 발표했던 "주니어 개발자의 우여곡절 디자인 시스템 개발기" 내용을 정리해 보려고 해요. 올해 초 회사에서 디자인 시스템을 새롭게 구축하면서 겪었던 다양한 시행착오와 배움을 중심으로, 디자인 시스템의 개념과 구축 방법을 살펴보고, 제가 직접 디자인 시스템을 개발하면서 마주했던 문제 상황들에 대해 함께 이야기해보려 해요.

이 글은 발표 내용의 축약 버전으로 작성되었어요. "SSAFYnale 기술 컨퍼런스" 주최 측에서 현재 발표 영상의 유튜브 업로드를 준비 중이며, 업로드 완료 시 추가로 첨부해 드릴게요. 더 자세한 내용은 추후 공개될 발표 영상을 참고해 주세요.

발표에 대한 회고 글은 아래 글을 참고해 주세요.👇
”2024 SSAFYnale 발표자로 참여한 이야기”

디자인 시스템이란?

디자인 시스템(Design System)이란 무엇일까요?

이 개념을 알아보기 전에 먼저 "시스템(System)"의 정의부터 살펴볼게요. 네이버 사전에서는 "시스템"을 "필요한 기능을 실현하기 위하여 관련 요소를 어떤 법칙에 따라 조합한 집합체"라고 정의하고 있어요. 핵심은 바로 "어떤 법칙에 따른 집합체" 라는 점이에요.

시스템

그렇다면 "디자인"이 더해진 "디자인 시스템"은 어떤 의미를 가질까요?

디자인 시스템은 서비스의 디자인과 개발을 일관되고 효율적으로 관리 및 개발하기 위해 만들어진 일종의 가이드라인이에요.

“왜 이런 가이드라인이 필요할까요?🤔”

처음 서비스 하나를 개발할 때는 디자이너가 만들어준 시안에 맞춰 페이지를 구성하고, 각자 필요한 UI 컴포넌트를 만들어 쓰는 것으로도 충분하죠. 그런데 서비스가 점점 커지고, 여러 명의 디자이너와 개발자가 함께 일하게 되면 문제가 생기기 시작해요.

같은 역할의 버튼들이 어떤 버튼은 둥글고, 어떤 버튼은 모서리가 날카롭고…

같은 기능의 카드 컴포넌트인데 마진이나 그림자가 미묘하게 다르고..

새로 들어온 팀원은 기존에 어떤 기준으로 UI가 만들어졌는지 몰라서 헤매고...

디자인 파편화

이런 상황이 반복되면 디자인 파편화가 생기기 시작해요. 😵

디자인 파편화란, 한 서비스 안에서 UI 스타일이나 컴포넌트 구현 방식이 제각각인 상태를 말해요. 이렇게 되면 서비스의 UI는 점점 ‘일관성’을 잃게 되고, 디자인이나 개발 속도도 느려지죠. 결국 사용자는 페이지마다 다른 룩앤필을 경험하게 되고, 유지 보수에 드는 비용도 계속 늘어나요.

이런 문제들을 예방하고, 더 효율적이고 일관된 방식으로 디자인과 개발을 이어가기 위한 해결책이 바로 디자인 시스템이에요.

디자인 시스템을 활용하면 디자이너와 개발자가 동일한 기준으로 작업할 수 있어요. 또한 자주 사용하는 컴포넌트를 재사용함으로써 중복 작업을 크게 줄일 수 있죠. 더 나아가 기획자, 디자이너, 개발자 간의 커뮤니케이션 비용도 눈에 띄게 감소하게 되죠.

디자인 시스템은 어떻게 만들까?

실제로 디자인 시스템을 만들려면 어떻게 해야 할까요?

좀 더 명확하게 디자인 시스템을 정의하자면, 다음과 같이 표현할 수 있어요.

"디자인 시스템은 디자인 원칙규격, 재사용할 수 있는 UI 패턴컴포넌트, 코드를 포괄하는 시스템"

이 정의를 기준으로 보면, 디자인 시스템을 구성하는 핵심 요소는 크게 두 가지로 나눌 수 있어요.

  1. 디자인 원칙과 규격
  2. 재사용할 수 있는 UI 패턴과 컴포넌트

먼저 첫 번째 요소인 디자인 원칙과 규격부터 살펴볼게요.

디자인 원칙과 규격

디자인 시스템의 가장 기초가 되는 건 **“디자인 원칙”**이에요.

이 원칙은 디자인 시스템이 어떤 방향성과 철학을 가지고 사용자 경험을 설계할지를 정의해요. 단순히 “예쁘게”가 아니라, 누구를 위해, 어떤 상황에서, 어떤 방식으로 디자인할지를 결정하는 기준이에요.

예를 들어 아래와 같은 원칙들을 세울 수 있죠.

  • 우리는 단순하고 명확한 UI를 지향한다.
  • 모바일 환경을 우선으로 구성한다.
  • 인터랙션은 단순하고 명확하게 한다.

이처럼 디자인 시스템만의 공통된 기준이 있어야, 디자이너가 바뀌거나 개발자가 새로 합류하더라도 같은 방향으로 일할 수 있어요. 마치 브랜드의 목소리를 맞추는 느낌이죠.

그리고 이 원칙을 기반으로 구체화되는 것이 바로 디자인 규격이에요.

디자인 규격이란, 말 그대로 서비스 전반에서 일관되게 사용하는 시각적 요소들의 기준을 말해요.

대표적으로는 다음과 같은 항목들이 있어요.

  • 색상(Color palette): 브랜드 컬러, 상태 컬러(성공/에러/경고 등)
  • 타이포그래피(Font styles): 제목/본문/캡션 등 텍스트 계층
  • 그리드 시스템과 간격(Spacing): 여백, 정렬 기준
  • 아이콘, 그림자, 경계(Border) 등 시각적 일관성에 필요한 요소

이 규격들이 잘 정리돼 있으면, 디자이너와 개발자가 같은 기준 위에서 작업할 수 있게 되죠. 그런데 여기서 한 가지 질문이 생겨요.

이 수많은 규격을 디자인과 코드 사이에서 어떻게 일관되게 유지할 수 있을까?

그 해답이 바로 **디자인 토큰(Design Token)**이에요.

디자인 토큰이란?

디자인 토큰(Design Token)은 디자인 시 사용하는 여러 자원, 규격들을 정리해 토큰이라는 변수에 담아 두는 것이에요.

대표적인 디자인 토큰으로는

  • Color Token
  • Typography Token
  • Border Radius Token
  • Shadow Token
  • Icon Token

등이 있어요.

실생활에서의 디자인 토큰

디자인 토큰이라는 개념이 조금 낯설게 느껴지실 수도 있어요. 하지만 사실 우리도 일상 속에서 이미 토큰 개념을 쓰고 있어요.

예를 들어, 우리가 티셔츠를 구매할 때 흔히 사이즈 표를 보고 S, M, L과 같은 사이즈를 선택하죠.

사이즈실제 치수(cm)
S90
M95
L100
XL105

이때 S, M, L, XL 도 일종의 사이즈 토큰이에요. 이 값들을 직접 90cm, 95cm로 외우고 쓰는 게 아니라, S, M이라는 공통된 명칭으로 통일해서 표현하죠.

디자인 토큰도 마찬가지예요. 우리는 컴포넌트를 만들 때 16px이나 12px 같은 숫자를 직접 쓰는 대신, textL, textS라는 의미 있는 이름을 사용해요. 이렇게 하면 디자이너와 개발자가 같은 언어로 소통할 수 있고, 스타일 변경이 생겨도 토큰만 수정하면 전체에 적용되며, 명확한 의미가 있는 이름이라 코드의 가독성과 유지 보수성이 좋아져요.

디자인 토큰을 코드로 변환

디자이너가 Figma에 정리한 디자인 토큰을 코드로는 어떻게 구현할까요?

예를 들어 디자이너가 아래와 같이 Color Token을 정리하였다고 가정해 볼게요.

Token NameHEX
red-50#FEF2F2
red-100#FEE2E2
red-200#FECACA
red-300#FCA5A5
red-400#F87171
red-500#EF4444
red-600#DC2626
red-700#B91C1C
red-800#991B1B
red-900#7F1D1D
green-50#F0FDF4
green-100#DCFCE7
blue-50#EFF6FF
blue-100#DBEAFE
grey-50#F9FAFB
grey-100#F3F4F6
white#FFFFFF
black#000000

위 Color Token을 이제 코드로 선언하면 다음과 같이 선언할 수 있어요.

CSS Variables 방식

/* globals.css */
:root {
  /* Red */
  --color-red-50: #FEF2F2;
  --color-red-100: #FEE2E2;
  --color-red-200: #FECACA;
  --color-red-300: #FCA5A5;
  --color-red-400: #F87171;
  --color-red-500: #EF4444;
  --color-red-600: #DC2626;
  --color-red-700: #B91C1C;
  --color-red-800: #991B1B;
  --color-red-900: #7F1D1D;
 
  /* Green */
  --color-green-50: #F0FDF4;
  --color-green-100: #DCFCE7;
  /* ...생략... */
 
  /* Blue */
  --color-blue-50: #EFF6FF;
  --color-blue-100: #DBEAFE;
   /* ...생략... */
 
  /* Grey */
  --color-grey-50: #F9FAFB;
  --color-grey-100: #F3F4F6;
  /* ...생략... */
 
  /* Black & White */
  --color-black: #000000;
  --color-white: #FFFFFF;
}

사용 예시

/* CSS 사용 시 */
.text-primary {
  color: var(--color-blue-700);
}
 
.input-error {
  border-color: var(--color-red-500);
}
/* Emotion CSS 사용 시 */
import { css } from '@emotion/react';
 
const buttonStyle = css`
  background-color: var(--color-blue-500);
  color: var(--color-white);
`;

JavaScript/TypeScript 방식

// colors.ts
export const COLORS = {
  red: {
    50: '#FEF2F2',
    100: '#FEE2E2',
    200: '#FECACA',
    300: '#FCA5A5',
    400: '#F87171',
    500: '#EF4444',
    600: '#DC2626',
    700: '#B91C1C',
    800: '#991B1B',
    900: '#7F1D1D',
  },
  green: {
    50: '#F0FDF4',
    100: '#DCFCE7',
    ...
  },
  blue: {
    50: '#EFF6FF',
    100: '#DBEAFE',
    ...
  },
  grey: {
    50: '#F9FAFB',
    100: '#F3F4F6',
    ...
  },
  white: '#FFFFFF',
  black: '#000000',
} as const;

사용 예시

/* Emotion CSS 사용 시 */
import { css } from '@emotion/react';
import { COLORS } from '@/tokens/colors';
 
const buttonStyle = css`
  background-color: ${COLORS.blue[500]};
  color: ${COLORS.white};
`;
/* Emotion styled 사용 시 */
import styled from '@emotion/styled'
 
const Button = styled.button`
  background-color: ${({ theme }) => theme.colors.blue[500};
  color: ${({ theme }) => theme.colors.white};
`

디자인 토큰의 코드 변환 자동화

디자인 토큰의 코드 변환 작업을 자동화하고 싶다면, Style Dictionary를 사용하는 걸 추천드려요.

Style Dictionary는 디자인 토큰을 다양한 플랫폼(iOS, Android, Web 등)에서 공통으로 사용할 수 있게 변환해주는 오픈소스 도구예요.

간단히 말하면, “디자인 토큰을 한 곳에서 정의하고, 여러 포맷(CSS, SCSS, JS, JSON, XML 등)으로 자동 변환해주는 빌드 도구”라고 생각하시면 돼요.

디자인 토큰을 활용한 스타일링 방식의 변화

디자인 토큰을 사용하면, 기존처럼 CSS 속성값을 매번 직접 입력하는 방식에서 벗어나, 사전에 정의된 토큰을 불러와 사용하는 방식으로 스타일링 방식이 달라지게 돼요.

이제 예시 디자인 가이드를 바탕으로 "찾아오시는 길" 메시지 텍스트를 스타일링하는 예시를 살펴볼게요.

Figma에서 "찾아오시는 길" 메시지 텍스트의 디자인 가이드를 확인하면, 아래와 같이 디자인 토큰 값과 연동된 정보를 볼 수 있어요.

”찾아오시는 길” 메시지 텍스트 디자인 가이드

디자인 가이드를 기반으로, Emotion의 Theme Provider에 Typography와 Color 같은 디자인 토큰이 미리 설정되어 있다면, 스타일링 코드 작성 방식이 다음과 같이 변화해요.

디자인 토큰 활용 이전 방식

const Message = styled.p`
  font-size: 16px;
  font-weight: 600;
  color: #121F34;
`

디자인 토큰 활용 후 방식

const Message = styled.p`
  font-size: ${({ theme }) => theme.font.size.textL};
  font-weight: ${({ theme }) => theme.font.weight.semibold};
  color: ${({ theme }) => theme.colors.grey[900};
`

재사용할 수 있는 UI 패턴과 컴포넌트

디자인 시스템을 만들기 위한 두 번째 필요 요소는 바로 재사용할 수 있는 UI 패턴과 컴포넌트에요. 여기서 컴포넌트(Component)란 재사용이 가능한 각각의 독립된 모듈로 볼 수 있어요.

Component

이는 마치 레고 블록과 같아요. 레고를 조립할 때를 떠올려볼게요. 하나의 집을 만든다고 해도, 그 집은 여러 개의 블록으로 이루어져 있어요.

  • 창문 블록
  • 문 블록
  • 벽돌 블록
  • 지붕 블록

이런 블록들을 하나하나 조립해서 전체 구조물을 완성하죠. 그리고 이 블록들은 다른 건물 만들 때도 재사용할 수 있어요.

LEGO

웹 페이지도 똑같아요.

  • Button 컴포넌트는 레고 블록 하나
  • Input 컴포넌트도 하나의 블록

이걸 조합해서 LoginForm이라는 건물 하나를 만들 수 있어요. 그리고 이 LoginForm은 또 다른 화면에도 붙일 수 있는 조립된 덩어리가 되죠.

즉 이렇게 조립된 구조는 재사용이 쉽고, 관리도 편하고, 일관성도 유지돼요. 무엇보다, 부품 하나만 수정해도 전체에 반영되니 유지 보수가 정말 쉬워지죠.

  • Button, Input → 단일 블록 (기본 부품)
  • LoginForm → 여러 블록을 조합한 구조물
  • LoginPage → 다양한 구조물이 모인 하나의 큰 세트

결국 디자인 시스템에서 말하는 컴포넌트는 색상, 간격, 폰트 크기까지 모두 규격화된 레고 블록과 같아요. 모든 팀원이 같은 레고 블록을 쓰기 때문에 디자이너와 개발자 간 소통이 쉬워지고, 서비스 전체가 일관된 스타일을 유지할 수 있으며, 변경 시 일괄 적용할 수 있어요.

디자인 시스템 확장 과정에서 맞닥뜨린 문제와 해결책

디자인 시스템은 만들었다고 끝이 아니에요. 처음에 잘 만들어도, 이후에 확장하고 유지 보수하는 과정에서 예상하지 못한 문제들이 하나둘씩 나타나기 시작해요. 기능이 늘어나고, 컴포넌트가 많아질수록 처음엔 보이지 않던 구조적 한계나 관리의 어려움이 드러나기 마련이죠. 그래서 디자인 시스템은 “완성”이 아니라, 계속해서 다듬고 발전시켜 나가야 하는 살아 있는 시스템이에요.

문제: 점점 복잡해지는 components 폴더

처음 디자인 시스템을 구축할 때는 components 폴더 안에 버튼, 인풋, 모달처럼 자주 쓰이는 공통 UI 컴포넌트를 하나씩 추가하면서 시작했어요. 하지만 디자인 시스템이 확장되며 컴포넌트를 추가해나가다 보니 components 폴더 하위에 수십 개가 넘는 컴포넌트가 일관된 구조 없이 누적되기 시작했죠.

// Components Directory Structure
📁components
  ├── 📁Typography
  ├── 📁Icon
  ├── 📁Button
  ├── 📁InputLabel
  ├── 📁Checkbox
  ├── 📁Radio
  ├── 📁Switch
  ├── 📁CheckboxModal
  ├── 📁RadioModal
  ├── 📁PageLayout
  ├── 📁Skeleton
  ├── 📁RadioModal
  ├── 📁Toast
  ├── 📁PageIndicator
  ├── 📁Tabs
  └── ...

문제는 여기서부터였어요. 어떤 컴포넌트들이 있는지 한눈에 파악하기 어려워졌고, 컴포넌트의 역할 구분이 점점 모호해졌으며, 관리 기준도 없어지면서 재사용 성과 유지 보수성이 모두 떨어지는 상황이 발생했어요.

처음엔 빠르게 만들 수 있지만, 시간이 지날수록 유지 보수에 발목을 잡는 구조가 되어 버렸죠.

해결: Atomic Design 도입

이 구조적 혼란을 해결하기 위해, Atomic Design을 제안하고 디자인 시스템에 도입했어요. Atomic Design은 화학점 관점에서 영감은 얻은 디자인 시스템 방법론이에요. 컴포넌트를 추상화 수준에 따라 계층화해서 나누는 방식이죠.

더 이상 “그냥 components 폴더에 다 넣는” 방식이 아니라, 명확한 기준에 따라 어떤 컴포넌트가 어디에 위치해야 할지를 정해주는 구조죠.

Atomic Design의 5단계

  1. Atoms (원자): 가장 기본적인 UI 요소. 더 이상 쪼갤 수 없는 단위예요.

예시: Button, Typography, Icon

  1. Molecules (분자): 2개 이상의 Atom을 조합해 하나의 역할을 갖는 작은 컴포넌트예요. 예를 들어 Label + Input + ErrorMessage를 묶은 Checkbox, Radio 같은 형태가 여기에 해당돼요.

예시 Checkbox, Radio, Switch

  1. Organisms (유기체): 여러 Molecule이 모여 상대적으로 더 큰 UI 영역을 구성해요.

예시: Header, Modal, Footer, CheckboxModal

  1. Templates (템플릿): Organism들을 조합해서 페이지의 레이아웃 구조를 정의해요.

예시: MyPageTemplate, ProductDetailLayout

  1. Pages (페이지): 템플릿에 실제 데이터를 넣어 완성된 하나의 화면이 되는 단계예요.

예시: MyPage.tsx, ProductDetailPage.tsx

레고로 다시 비유하면 Atoms, Molecules, Organisms을 다음과 같이 표현할 수 있어요.

Atomic Design LEGO

이를 실제 컴포넌트에 적용해보면 다음과 같아요.

Atomic Design Component

왜 Atomic Design이 유용할까?

Atomic Design은 다음과 같은 이점들을 갖고 있어요.

  • 컴포넌트를 추상화 수준에 따라 나누기 때문에 구조가 일관되고, 명확해요.
  • 재사용 성과 유지 보수성이 크게 높아져요.
  • 컴포넌트가 수십, 수백 개로 늘어나도 체계적으로 정리할 수 있어요.

Atomic Design으로 리팩터링

기존 컴포넌트를 Atomic Design 구조로 리팩터링 하여 다음과 같이 체계적으로 정리했어요. 이 과정에서 저는 “Templates” 대신 “Layouts”라는 용어를 사용했는데, 이렇게 함으로써 해당 계층의 역할을 더 명확하게 표현하고자 했어요.

Before

📁components
  ├── 📁Typography
  ├── 📁Icon
  ├── 📁Button
  ├── 📁InputLabel
  ├── 📁Checkbox
  ├── 📁Radio
  ├── 📁Switch
  ├── 📁CheckboxModal
  ├── 📁RadioModal
  ├── 📁PageLayout
  ├── 📁Skeleton
  ├── 📁RadioModal
  ├── 📁Toast
  ├── 📁PageIndicator
  ├── 📁Tabs
  └── ...

After

📁components
  ├── 📁atoms       
     ├── 📁Typography
     ├── 📁Icon
     ├── 📁Button
     ├── 📁InputLabel
     └── ...     
  ├── 📁molecules
     ├── 📁Checkbox
     ├── 📁Radio
     ├── 📁Switch
     └── ...     
  ├── 📁organisms
     ├── 📁CheckboxModal
     ├── 📁RadioModal
     ├── 📁Header
     └── ...   
  └──  📁layouts
        ├── 📁PageLayout
        └── ...

Atomic Design의 단점과 한계는?

Atomic Design은 장점만 있는 완벽한 구조일까요? 그렇지 않아요. Atomic Design에도 단점과 한계가 존재해요.

  • 구분이 애매함: 어떤 컴포넌트가 Atom 인지 Molecule 인지 사람마다 기준이 다를 때가 있어요.
  • 오히려 복잡해질 수 있음: 과하게 쪼개면 파일만 늘어나고 개발 속도는 느려질 수 있어요.
  • 디자이너와 기준이 다를 수 있음: 디자이너는 하나의 덩어리로 본 UI를 개발자는 나눠서 보기 때문에 소통이 어긋날 수 있어요.
  • 초기 설계가 과할 수 있음: 작은 규모의 프로젝트에서는 오히려 부담스러운 구조일 수 있어요.

결국 이러한 단점과 한계점을 보완하기 위해서는 Atomic Design에 대한 명확한 이해와 기준을 디자이너와 개발자 동료들 간에 공유해야 해요.

이 많은 양의 컴포넌트들, 테스트와 공유는 어떻게? — Storybook

디자인 시스템을 만들다 보면 이런 고민도 생기기 시작해요.

“이 많은 컴포넌트들이 제대로 동작하고 있는지, 그리고 디자인 가이드에 맞게 잘 스타일링됐는지 어떻게 확인하고, 동료들과 공유하지…?”

초반에는 몇 개 안 되는 컴포넌트를 직접 페이지에 붙여보면서 확인할 수 있지만, 컴포넌트가 30개, 50개, 그 이상 늘어나기 시작하면 개별 상태를 확인하고, 피드백을 주고받는 과정 자체가 점점 비효율적이 돼요.

그래서 저는 디자인 시스템을 시작할 때부터 컴포넌트의 동작과 스타일을 테스트하고, 동료들과 쉽게 공유하기 위한 도구로 Storybook을 도입했어요.

Storybook이란?

Storybook은 UI 컴포넌트를 페이지와 분리된 환경에서 독립적으로 테스트하고, 문서화하고, 팀과 공유할 수 있게 도와주는 도구에요. 페이지에 붙이지 않아도 각 컴포넌트를 바로 확인할 수 있고, 다양한 상태를 미리 정의해두면 버튼, 모달 같은 컴포넌트를 디자이너나 기획자가 직접 Storybook에서 확인하고 피드백할 수 있어요. 또한, props 정보와 사용 예제를 함께 문서화할 수 있어서, 동료 개발자나 신규 입사자도 Storybook만 보면 컴포넌트 사용법을 빠르게 이해하고 바로 개발에 활용할 수 있죠.

실제로 저는 디자인 시스템 내 약 70개 이상의 컴포넌트를 모두 Storybook에 등록하고, 각 컴포넌트마다 Enabled, Pressed, Disabled, Loading, Error 등 다양한 상태 시나리오(Story)를 정의했어요. 디자이너는 이를 보고 Figma 디자인과 비교해 빠르게 디자인 QA를 진행했고, 동료 개발자들은 문서화된 컴포넌트를 보며 쉽게 재사용할 수 있었어요.

결과적으로 Storybook은 우리 디자인 시스템의 테스트, 문서화, 협업을 위한 핵심 도구가 되었고, 컴포넌트 수가 더 많아진 지금까지도 유지 보수성과 확장성을 안정적으로 이끌어주고 있어요.

디자인 시스템의 장점?

디자인 시스템을 개발하기 위해서는 상당한 초기 비용이 들어요. 하지만 개발이 완료되면 팀 전체가 누리게 되는 분명한 장점들이 있어요. 특히 생산성, 일관성, 협업 효율 세 가지 측면에서 효과가 두드러졌어요.

1. 생산성 향상 – “한 번 만들고, 계속 조립해서 쓰기”

디자인 시스템을 도입하고 나서 가장 먼저 체감한 건 컴포넌트를 훨씬 빠르게 조립할 수 있다는 점이었어요. 예를 들어 버튼, 아이콘, 텍스트 필드 같은 기초 컴포넌트들이 이미 재사용 가능한 형태로 정의되어 있다 보니, 새로운 페이지를 만들 때도 일일이 새로 만들 필요 없이, 기존 부품을 조립하듯 빠르게 구성할 수 있었죠. 이는 단순히 페이지 개발뿐만 아니라 새로운 컴포넌트를 만들 때에도 마찬가지였어요.

또 하나 크게 느낀 건 디자인 토큰의 힘이에요. 예를 들어 서비스의 Primary Color를 변경해야 하는 상황이 생겼을 때, 기존에는 색상 코드를 일일이 수정해야 했다면, 이제는 --color-primary 같은 토큰 하나만 수정하면 전체 UI에 바로 반영돼요. 이런 구조 덕분에 기존에는 며칠씩 걸리던 작업이 몇 분 만에 끝나는 일도 많아졌고, 디자인 변경에 대한 두려움도 훨씬 줄었어요.

2. 일관성 향상 – “같은 UI, 같은 경험”

디자인 시스템이 없을 때는 화면마다 버튼 모양이 다르고, 마진도 들쭉날쭉한 경우가 종종 있었어요. 심지어 어떤 버튼은 Pressed 효과가 있고, 어떤 건 없는 식으로, 작은 디테일의 불일치들이 쌓여 전체 사용자 경험을 흐리게 만들곤 했죠.

디자인 시스템을 도입하면서 모든 UI 요소가 공통된 규칙과 스타일 안에서 관리되다 보니, 어떤 화면이든 일관된 디자인과 사용자 경험을 제공할 수 있게 됐어요. 특히 팀원마다 코드를 작성하는 스타일이 달라도, 컴포넌트는 항상 같은 기준으로 렌더링 되기 때문에 디자인 QA나 리뷰에서도 발견되는 UI 이슈가 확연히 줄었어요.

3. 협업 효율 향상 – “상태 정의는 한 번이면 끝”

이전에는 디자이너가 컴포넌트 디자인을 전달할 때 Enabled, Pressed, Disabled, Loading… 다양한 상태를 매번 새로 정의해서 전달해줬어요. 그걸 또 개발자가 그대로 구현하고, QA가 다시 테스트하는 식의 반복적 커뮤니케이션이 계속됐죠.

디자인 시스템에선 이런 반복을 줄일 수 있어요. 예를 들어 버튼 컴포넌트는 이미 Storybook에서 모든 상태(Enabled, Pressed, Disabled, Loading)가 정의돼 있고, 디자이너와 개발자 모두 그걸 참고해서 그대로 쓰면 되니 작업 속도가 훨씬 빨라졌어요. 이 구조 덕분에 디자이너는 모든 화면마다 상태 디자인을 새로 만들지 않아도 되고, 개발자도 디자이너의 별도 가이드를 기다리지 않고 바로 개발에 진행할 수 있게 됐어요.

디자인 시스템을 잘 적용하려면?

디자인 시스템은 만들기만 한다고 끝이 아니에요. 서비스에 잘 적용하고, 이 시스템을 지속적으로 유지하는 것은 정말 어려운 일이에요. 이를 효과적으로 수행하기 위해서는 다음 두 가지가 반드시 실행되어야 해요.

1. 확장성

디자인 시스템은 시간이 지날수록 컴포넌트가 계속 늘어날 수 있기 때문에, 처음부터 확장 가능성을 고려한 구조로 만드는 게 정말 중요해요. 예를 들어 버튼 하나를 만들더라도, 나중에 primary, secondary, error처럼 변형이 생길 수 있다는 걸 염두에 두고 스타일과 기능을 분리해두면 나중에 수정 없이도 쉽게 확장할 수 있어요. 또한 디자인 토큰, 컴포넌트 폴더 구조도 일관된 규칙과 계층 구조를 갖추는 것이 지속 가능한 디자인 시스템의 핵심이에요.

2. 적극적 사용

아무리 잘 만든 디자인 시스템이라도 디자이너나 개발자가 실제로 사용하지 않으면 의미가 없어요. 페이지마다 새로운 컴포넌트를 만들고, 기존 토큰을 무시한 스타일이 쌓이기 시작하면 결국 디자인 시스템은 방치된 문서처럼 돼버리거든요. 그래서 중요한 건 “잘 만드는 것”보다 “잘 쓰이게 하는 것”이에요. 팀이 자연스럽게 디자인 시스템을 먼저 참고하고 활용하는 흐름이 정착돼야 비로소 그 시스템이 살아 움직이기 시작한다고 생각해요.

디자인 시스템은 처음부터 잘 적용했는가?

저도 디자인 시스템을 처음부터 잘 만들진 못했어요. 사실 이번에 디자인 시스템을 만드는 것은 v2.0 버전이에요. 작년에 v1.0 버전을 처음 만들었을 때, 확장성에 대한 고민이 부족한 채로 시스템을 설계했어요. 디자인 토큰도 정리가 덜 돼 있었고, 컴포넌트들도 단순히 "보여지는 것"에만 초점을 맞춰 만들다 보니 점점 새로운 요구사항이 나올 때마다 대응이 어려워졌죠.

결국 어떻게 됐을까요?

디자이너는 새로운 페이지를 만들 때마다 기존 시스템을 사용하지 않고 컴포넌트를 새로 디자인해서 넘겨주게 되었고, 개발자도 그걸 기반으로 시스템 바깥에서 컴포넌트를 만들기 시작했어요.

그렇게 자연스럽게 v1.0은 점점 “사용되지 않는 시스템”이 돼버렸고, 디자인 시스템은 사실상 죽은 코드처럼 방치되기 시작했죠.

이 경험은 저에게 꽤 큰 실패였지만, 동시에 디자인 시스템에서 확장성과 적극적인 사용이 얼마나 중요한지를 뼈저리게 느낀 계기였어요. 그래서 이후 v2.0 버전을 준비하면서는 이 실패를 거울삼아 완전히 구조를 다시 잡고 접근했어요.

마무리

디자인 시스템을 구축하는 여정은 생각보다 쉽지 않아요. 처음엔 단순히 공통 컴포넌트를 모아두는 것처럼 보이지만, 막상 만들어보면 구조, 확장성, 팀의 사용성, 협업 방식까지 수많은 고민이 따라오게 되죠.

저 역시 처음엔 실패도 겪었고, “정말 이게 잘 쓰일까?” 하는 회의감도 들었지만, 돌아보면 그 모든 과정을 거쳤기에 지금의 디자인 시스템이 만들어졌다고 생각해요. 물론 지금도 여러 새로운 고민들이 생기고 있어요.

이번 글에서는 디자인 시스템이 무엇인지, 어떻게 만들 수 있는지, 그리고 제가 직접 경험한 시행착오까지 이야기해봤어요. 디자인 시스템을 처음 시작하는 팀, 혹은 운영 중이지만 어려움을 겪고 있는 분들에게 현실적인 힌트와 공감이 되는 이야기가 되었길 바라요. 누구나 처음은 서툴 수 있지만, 지속적으로 개선하고, 팀과 함께 써 나가면 디자인 시스템은 분명히 팀의 강력한 부스터가 될 거예요.

참고 자료

Brad Frost - Atomic Design Methodology

Storybook