메뉴 버튼
썸네일 이미지
2025년 6월 29일

정의되지 않은 UI 지옥에서 살아남기 – 주니어 개발자의 디자인 시스템 구축기(1)

design system
frontend
react
figma
shadcn

💬 서론 및 개요

레거시 같던 블로그 써야지 첫 글로 디자인 시스템에 대해 쓰게 되었습니다.

이번 글에서는 동료들과 디자인 시스템을 만들게 된 배경부터 실제 구축 과정에서 마주했던 어려움과 해결 방안, 그리고 앞으로 개선해 나가야 할 방향까지 좌충우돌 겪었던 일들을 정리하고 또 공유하기 위해 이 글을 썼습니다.

(저희 팀 특성 상 다른 회사, 팀과 다를 수 있기에 가볍게 읽어주시면 좋을 것 같아요.)



🤔 왜 디자인 시스템을 만들려 했을까?

1) 배경 : 이런 서비스를 하고 있어요.

저희 팀은 AI를 활용한 제품들로 감지된 이벤트를 분석, 시각화하는 소프트웨어를 개발하고 있습니다.

다만 하나의 소프트웨어가 아닌 A1, A1-1, A2, A2-1 등 각기 다른 제품마다 비슷한 기능을 제공하지만, 제품별 특성에 따라 차이가 있는 여러 개의 소프트웨어를 운영, 유지보수하고 있었습니다.

덕분에 관리해야 할 프로젝트가 여러 개로 분산되어 있었는데요.

제가 입사했을 때는 이 여러 서비스들을 하나로 통합하려는 포털 서비스의 핵심 기능들이 어느 정도 완성되어 가는 단계였는데요. 빠른 일정 내에서 진행하다보니 개발을 진행하면서 아래와 같은 문제들을 발견할 수 있었습니다.


2) 이런 문제들이 있었어요.

저희 회사는 제품군을 중심으로 팀이 나뉘어져 있었고 저희 팀은 얼마 안된 신규 사업으로 꾸려진 팀이라 디자이너나 기획자가 없었기에 개발자가 주축이 되어 서비스를 만들고 있었습니다.

기존에는 디자인 라이브러리를 그대로 가져다 쓰거나, 개발자가 직접 스타일을 임의로 조정하는 일이 많았습니다.

문제 예시

구체적인 예시로 각 개발자가 서로 다른 스타일 가이드와 컨벤션을 따르다 보니, 공통 컴포넌트를 재활용하는 방법이나 CSS 속성 추가 방식도 제각각이었어서 같은 버튼 디자인이라도 각 페이지마다 다르게 구현되는 경우가 많았습니다. 이런 일관되지 않은 코드들로 인해 새로 합류한 팀원들뿐만 아니라 기존 회사 내에서도 기존 코드를 이해하고 리뷰하는 데 어려움을 겪고 있었습니다.

디자인 역시 마찬가지였는데요. 디자인 가이드나 컴포넌트 라이브러리가 정리되어 있지 않아, 새로운 기능이나 페이지를 추가할 때마다 일관성 있는 디자인을 유지하기 어려웠고 추후에 신제품이 출시되었을 때 신규로 개발하게 되더라도 바로 활용할 수 있는 일관된 컴포넌트 모음집들이 있으면 좋겠다는 기존 작업자들 간의 이슈사항들이 있었습니다.


3) 문제점을 요약해보자면

  1. 디자인 개편 필요
    기존 UI가 통일되지 않아, 리디자인 또는 리팩토링이 필요한 상황

  2. 일관성 없는 컴포넌트 구현
    개발자마다 각기 다른 스타일과 방법으로 UI 구현 → 사용자 경험 분산

  3. 협업 비용 증가
    코드 리뷰와 유사 기능 구현 시, 레거시 코드 해석 및 재작업으로 리소스 낭비

  4. 공통 컴포넌트 부재로 인한 반복 작업
    프로젝트마다 동일한 UI를 새로 만들거나 복붙하는 일이 다반사로 비효율적이고 오류 발생 가능성 증가




📃 어떻게 디자인 시스템을 정의하고 만들까?

디자인 시스템을 본격적으로 만들기로 했을 때 팀원들과 함께 어떻게 정의하고 구축할지에 대해 논의했습니다. 여러 기업들의 디자인 시스템 사례를 참고하며 제한된 일정 내 팀 리소스 활용을 위해 간단한 컴포넌트부터 쉽게 구축하자는 방향을 작은 팀이 빠르게 만들고 적용할 수 있는 범위부터 시작하기로 했습니다.


1) 어떻게 정리할까?

디자인 시스템 정리를 위해 역할별 관점에서의 기준 설정 또한 필요했는데요. 디자이너가 없다보니 디자이너 + 개발자 두 역할의 입장 고민 또한 필요했습니다.

각각의 역할에서 필요한 기준과 사용 방식을 정리해 나갔습니다.


디자이너의 입장으로 생각했을 때


개발자의 입장으로 생각했을 때

이런 점들을 고민하면서 디자인부터 진행했고, 프론트 팀원분들과 이야기하며 기본적인 디자인 시스템 구조부터 피그마를 활용해 정리해두었습니다.

디자인 시스템 파운데이션

우선, 디자인 시스템의 기본이 되는 Foundation 단계에서는 색상, 라운드, 서체, 여백 등을 먼저 정의하는 것부터 진행했는데요. 아래처럼 기본 근간이 되는 색상은 작업의 편의를 위해 색상의 경우, Tailwindcss에서 사용하는 컬러를 그대로 활용했고, 서체는 피그마에서 정의해둔 그대로 tailwind.config.ts에 정의해두었습니다.

이후 디자인을 보고 개발에서도 동일하게 디자인 시스템을 적용하고 사용할 수 있도록 하는 작업을 진행했습니다. 기본이 되는 서체, 색상, 라운딩 등을 정해두면 해당 요소를 활용한 컴포넌트와 아래처럼 디자인에 정의한 variants와 config 내 fontSize가 동일하게 정의해두었습니다.

      fontSize: {
        'headline-lg': [
          '1.75rem',
          {
            lineHeight: '2.5rem',
            letterSpacing: '-0.01875rem',
            fontWeight: '700',
          },
        ],
        // ...
        }

해당 내용처럼 최대한 디자인과 개발 작업 간의 싱크를 동일하게 맞추는 작업을 먼저 해두고 각 button, tab과 같은 컴포넌트 연결 작업을 시작했습니다.


2) 디자인 시스템 구조는 HeadlessUI를 기반으로

저희는 기존에 프로젝트에서 Shadcn UI를 활용하고 있었는데요.

Shadcn UI는 아래와 같은 특징과 장점이 있어 디자인 시스템 구축에도 긍정적으로 활용할 수 있었습니다.


디자인 시스템에 알맞는 장점으로는,

  1. 직접 소유 가능한 컴포넌트 코드
    외부 라이브러리에 종속되지 않고, 우리 프로젝트 내부에 소스 코드로 관리함으로써 수정 및 확장이 매우 용이했습니다.

  2. 접근성이 보장된 Headless 컴포넌트 구조
    Dialog, Dropdown, Popover 등 사용성이 중요한 컴포넌트는 Radix UI 기반으로 설계되어 있어, 접근성 기준을 기본적으로 충족합니다.

  3. Tailwind 기반의 일관된 스타일링
    유틸리티 클래스만으로도 빠르게 일관된 UI를 구현할 수 있었고, 기존 팀의 개발 경험과도 잘 맞아 빠르게 정착할 수 있었습니다.

  4. CVA(class-variance-authority)를 활용한 스타일 관리
    variant, size, rounded 등의 속성을 명시적으로 구조화해 코드의 가독성과 재사용성을 모두 확보할 수 있었습니다.

이런 Shadcn UI를 활용해 팀의 디자인 시스템 구축과 개발 효율성을 동시에 향상시킬 수 있는 핵심 도구로 사용했습니다.


3) 버튼 하나부터 시작된 디자인 시스템 정리

Shadcn UI를 활용하면서, 저희 팀의 디자인 시스템 구축도 본격적으로 시작할 수 있었습니다. 그 첫 출발점은 아주 단순하지만 가장 자주 쓰이는 컴포넌트, 버튼(Button) 이었습니다.

저희 팀에서 디자인 시스템을 만들었을 때 달성하고자 했던 1차 목표는 ‘지금 너무 제각각으로 쓰이고 있는 컴포넌트들을 정리해서 일관된 UI를 만들자’였습니다.

그래서 초기에는 유연성보다는 일관성에 무게를 두고 컴포넌트를 설계했습니다. 필요 이상으로 많은 props는 줄이고, 정해진 variant, size, rounded 안에서 사용되도록 구성했습니다.



Button 컴포넌트 예시

const buttonVariants = cva(
  "inline-flex w-fit items-center justify-center ...",
  {
    variants: {
      variant: {
        outline: "border border-gray-300 text-gray-500 ...",
        primary: "bg-orange-500 text-white ...",
        destructive: "bg-red-500 text-white ...",
        // ...
      },
      size: {
        lg: "h-12 px-4 py-2 ...",
        sm: "h-9 px-3 py-2 ...",
        xs: "h-7 p-1 ...",
      },
      rounded: {
        default: "rounded",
        full: "rounded-full",
      },
    },
    defaultVariants: {
      variant: "outline",
      size: "lg",
      rounded: "default",
    },
  },
);

const Button = React.forwardRef(({ variant, size, rounded, ...props }, ref) => {
  const Comp = props.asChild ? Slot : "button";
  return (
    <Comp
      className={cn(buttonVariants({ variant, size, rounded }))}
      ref={ref}
      {...props}
    />
  );
});

이런 구조 덕분에 팀 내에서 버튼 컴포넌트를 사용할 때 어떤 버튼을 어떤 상황에서 써야 하는지 명확해졌고, 디자인 가이드와 코드가 괴리 없이 자연스럽게 이어졌습니다.


4) 버튼 하나 만드는데 리뷰를 3번?

버튼은 정말 흔한 컴포넌트라 쉽게 끝날 줄 알았지만, 생각보다 많은 논의가 필요했습니다.


이런 고민들을 나누면서 코드 리뷰도 3번 이상 오가면서 지금의 버튼 컴포넌트가 나왔는데요. 디자인 시스템을 발전시켜가면서 또 우리 팀의 사용 방식에 딱 맞게 정돈될 수 있었고, 다른 컴포넌트를 만들 때도 참고할 수 있는 좋은 템플릿이 됐습니다.


5) Figma와의 연결 – 개발과 디자인이 만나는 지점

버튼 컴포넌트를 구현할 때 가장 중점적으로 고려한 부분 중 하나는
Figma에서 정의된 Variant 구조를 실제 코드의 props와 최대한 일치시키는 것이었습니다.

variant, size, rounded 같은 속성들은 Figma의 Variants 패널에서 설정한 그대로 코드에서도 동일한 이름과 구조로 재현되도록 구성했습니다. 해당 방식대로 시스템을 설계했을 때 디자인을 확인하는 것만으로도 어떤 props를 사용할지 자연스럽게 유추할 수 있도록 했습니다.

디자이너 없이 개발자가 직접 UI를 조립해야 하는 상황이었기에, Figma 안에서 버튼 하나를 보더라도

저희 디자인 시스템의 1차 목표였던 “디자인만 봐도 개발자가 어떤 props를 써야 할지 알 수 있는 구조”였습니다. 디자인과 개발의 언어가 다르지 않도록, 양쪽이 같은 언어를 쓰는 구조를 만드는 것.

그게 저희가 지향했던 디자인 시스템의 출발점이었습니다.


6) 컴포넌트를 통합하며 얻은 것

버튼 외에도 Input, Select, MultiSelect, Pagination, Table, Tab 등 자주 쓰는 컴포넌트들을 디자인 시스템에 포함시켰고, 이제는 어느 프로젝트에서든 같은 컴포넌트를 가져다 쓸 수 있게 되었습니다.

가장 큰 변화는 불필요한 코드 리뷰가 줄어들고, “이거 어떤 스타일 써야 해?” 같은 질문이 사라졌다는 점입니다. 정해진 컴포넌트를 중심으로 작업하면서,디자인 정의의 예외 사항도 자연스럽게 줄었고 개발자 간 커뮤니케이션 비용도 눈에 띄게 줄었습니다.



🛠️ 개선 필요 및 작업 사항

현재 A 서비스에 디자인 시스템을 구축해 적용한 상태지만 이 디자인 시스템은 특정 프로젝트에 종속된 형태로 존재하고 있어, 다른 서비스에서는 직접적으로 활용할 수 없다는 점이 아쉬운데요.

예를 들어, B 서비스에서 동일한 버튼 컴포넌트를 쓰고 싶어도 기존 코드를 복사해 사용하거나 새로 만들어야 하기 때문에 이 과정에서 중복 구현이 발생하고, 시스템 전반의 일관성도 흐트러지게 됩니다.

이러한 문제를 해결하기 위해, 디자인 시스템을 공통화 및 패키지화(npm 라이브러리화)하는 작업할 예정입니다.

디자인 시스템을 독립 레포지토리 혹은 모노레포 구조로 분리하여, 어느 서비스에서도 사용할 수 있도록 설계하고, 내부 npm 레지스트리 또는 GitHub Packages 등을 통해 패키지로 배포 가능한 구조를 마련하려 합니다 😊



🔚 끝으로

주니어 개발자로서 또 디자이너였던 이전 경험으로 디자인 시스템의 필요성을 이해하고 첫 걸음으로 1차 문제를 해결했다는 것에 의의를 두고 디자인 시스템을 개선해나가보려합니다. 디자인 시스템을 좀 더 개선해서 두 번째 글로 다시 돌아오겠습니다.

읽어주셔서 감사합니다 😊