기획자도 디자이너도 없는 환경에서 매번 UI를 새로 만들던 고통 끝에, shadcn/ui의 Headless 구조와 코드 소유권에 주목해 디자인 시스템을 직접 만들었습니다. primitive UI 개발 없이 스타일만 얹는 방식으로 27개 컴포넌트를 30일 만에 완성, 이후 4개 앱을 50일 안에 찍어낸 경험기입니다.
기획자도 디자이너도 없는 환경에서 매번 UI를 새로 만들던 고통 끝에, shadcn/ui의 Headless 구조와 코드 소유권에 주목해 디자인 시스템을 직접 만들었습니다. primitive UI 개발 없이 스타일만 얹는 방식으로 27개 컴포넌트를 30일 만에 완성, 이후 4개 앱을 50일 안에 찍어낸 경험기입니다.
Sangwoo Yang
@IGhost-P

FE 개발을 하다 보면 이제는 흔하게 들리는 ‘디자인 시스템’이라는 게 있다. 내가 처음 이 단어를 들었던 건 얼추 2023년쯤부터였던 것 같다. 그 전까지는 디자인 시스템보다는 “디자이너가 제공한 디자인 가이드에 맞춰 개발한다”는 느낌에 가까웠다. 마치 MUI( v5 이전처럼) 디자이너의 스타일에 맞춘 CSS 파일들이 쭉 있고, 그걸 그대로 따라 하는.
그렇다면 디자인 시스템이란 무엇일까?
디자이너가 만든 디자인을 코드로 구현해, 코드에 대한 일관성을 유지하는 것.

그렇다면 디자인 시스템을 어떻게 하면 재사용성 있게 개발할 수 있을까? 2023년 당시에는 Atomic Design이 유행이었다. (아마 우아한테크코스였나, 거기서 프로젝트 할 때 많이 쓴다 해서 FE 취준생들이라면 한 번쯤 써봐야 한다는 분위기였다.) UI 디자이너들이 UI의 레이어를 Atom — Molecules — Organism — Page로 분리해서 작업하고, FE는 또한 같은 레이어를 코드로 개발하고 나서, Storybook으로 보여주는 게 일이었다.
styled-component, UnoCSS, Emotion 등등… Atom부터 개발을 해야 했기에 primitive한 UI 개발에 대한 공수가 정말 많이 들었다. 서비스마다 UI와 디자인이 다르기에 매 서비스마다 Atomic Design을 새로 개발해야 했다.
만약 디자인 가이드 없고, 빠르게 개발해야 한다면 (like 단순 사이드 프로젝트) 다양한 디자인 프레임워크 (Chakra UI, MUI v5 등)를 사용해서 개발하는 방법도 있었다.

처음 취업했을 때는 당연히 디자인 시스템이 회사에모두 마련되어 있을 거라 생각했다.(중견, 대기업 둘다 가봤다)
하지만 그건 일부 유니콘 기업이나 B2C에 집중한 기업들이나 그렇고, 실상 디자인 가이드조차 없는 경우가 많았다.
당시 우리 회사도 디자인 가이드나 시스템은 없었고, 팀 디자이너가 만든 디자인에 맞춰서 매번 개발하는 방식이었다. 다행히 실력이 정말 좋으신 웹 퍼블리셔 분이 계셔서, 비즈니스 로직만 없는 디자인이 모두 적용된 React 코드까지 만들어주셨다. FE 개발자들은 비즈니스 로직만 만들면 됐다.
진짜 편했다.
(하지만 서비스가 망해서 다른 서비스를 개발하러 가게 됐고, 웹 퍼블리셔 분이랑도 다른 팀으로 가게 되었다…)

이번에는 백오피스 쪽 개발을 담당하게 되었다. 백오피스이다 보니 디자이너는 물론 기획자도 없었고, 그저 운영 효율을 위해 만들어내는 콘솔들뿐이었다. 심지어 레거시 프로젝트를 담당했기에 Vue + Quasar를 썼다.
근데 참 웃긴 게, 디자이너랑 기획자가 없으니 화면 담당하는 FE가 화면 기획까지 담당해야 했다. 디자인 프레임워크를 쓰면서도 커스텀 디자인이 필요한 경우가 많았다.
그렇다고 화면으로 뚝딱 만들고 보여주는 게 아니라, Figma로 어떻게 화면을 디자인해야 할지 보여줘야 하는데… 디자인 프레임워크에서 Figma assets을 주는 경우가 아니라면, 또는 없는 디자인을 개발한다면, 매번 새로운 디자인 assets을 만들고 그걸 또 코드로 만들어야 했다.
그렇다고 디자인 프레임워크가 커스텀을 잘할 수 있는 것도 아니다. 라이브러리의 코드를 바꿀 수가 없기 때문이다.
가령 Dropdown의 스타일을 수정하고 싶다면, HTML DOM에서 className 또는 id를 확인해 !important를 붙여가며 스타일을 수정했다.
(이게 맞나?? 이럴거면 왜 디자인 프레임워크를 쓰는건데..)

고통을 받으며 백오피스를 개발하다 보니, 회사에서도 백오피스에 대한 개선이 필요하다고 느꼈나 보다. 전반적인 디자인 가이드가 제공되기 시작했고, 마침 새로운 서비스를 개발해야 하는 상황이어서 새 서비스 디자인 가이드에 맞춰 디자인 시스템을 만들려는 시도가 생겼다.
다만 Atomic Design 시스템 때 했던 것처럼, 모든 primitive한 UI를 직접 개발했다. 시간이 많이 들 수밖에 없고, 재사용성과 퀄리티, 유지보수를 생각하면 그렇게 막 간단하게 만들 수 있는 노릇도 아니었다.
근데 실제로 이러한 디자인 시스템을 개발하는 것에 대한 공수를 윗사람들이 알까?
FE가 아니라면 “고작 UI 하나 만드는데 왜 이리 오래 걸리는 거냐?” 싶을 거다.
그렇다. 우리 회사에서는 그런 것 따위 신경 쓰지 않는다. 그러니 UI 개발하는 건 따로 프로젝트화 시킬 수 없고, 서비스 개발을 하는 동시에 디자인 시스템도 만들어야 했다. 마치 디자인 시스템을 개발하는 건 부가적인 일이라, 성과로 측정하기도 프로젝트로 보고하기도 애매했다.
그러다 어쩌다 저쩌다 해서 새로운 서비스가 드롭되었고, 애매하게 만들었던 디자인 시스템 또한 다른 곳에서 사용하기에 애매한 수준이 되어버렸다.

서비스가 드롭되고, 기간이 조금 여유가 생겼다. 약 2달 정도?
나는 이 틈에 FE 기술 스택을 전부 전환하고 싶었고, 2달 뒤에 개편할 서비스 + 통합 프로젝트 등… 신규 서비스를 위해서라도 디자인 시스템은 필수적으로 필요하다고 생각했다.
그리고 디자인 시스템 개발을 정식적으로 프로젝트화 시켜서 만들어야 한다고.
그래서 팀원들에게 디자인 시스템 개발 + React 전환을 제안했고, shadcn/ui를 공유했다.
실제로 써봤을 때 경험이 제일 좋았다:
로직과 스타일이 분리되어 있음 (Headless)
Primitive UI는 Radix UI에서 관리함
Open code 형식이라 스타일을 바꾸고 싶다면 해당 컴포넌트에서 바꾸면 됨 (코드 소유권)
Figma 파일 제공
디자인 가이드에 없는 여러 UI도 색상, radius 등만 얼추 맞추면 비슷함
Martin Fowler 사이트에 실린 글에서 Headless Component를 이렇게 정의한다:
“A Headless Component is a design pattern where a component is responsible solely for logic and state management without prescribing any specific UI. It provides the ‘brains’ of the operation but leaves the ‘looks’ to the developer.”
(Headless Component는 로직과 상태 관리만 담당하고, UI는 개발자에게 맡기는 패턴이다. ‘뇌’는 제공하지만 ‘외모’는 개발자가 결정한다.)
이 중 제일 좋았던 건 당연히 1번과 2번이다.
나는 회사에서 전문적으로 이러한 디자인 시스템을 철저하게 관리하고 (like 토스, 당근, 네이버 등) primitive UI를 내부 사용자들이나 전문 팀이 계속 관리해주는 게 아니라면… 당연히 오픈소스가 낫다고 생각한다.
(우리 회사 FE 전부 vs Radix UI… 누가 더 관리를 잘해줄까?)
그리고 감사하게도 팀원 모두가 의견을 따라주어서 디자인 시스템 프로젝트를 시작하게 되었다.
앞서 회사에서 제공한 디자인 가이드가 있으니, 디자인 토큰을 사용해서 shadcn/ui에서 Radix UI 위에 덮은 디자인 토큰을 갈아끼우면 되겠다…! 라고 생각했다. 뭐, 없는 부분은 AI를 활용하고…
하지만 현실은 그렇게 녹록하지 않았다.
일단 회사에서 제공해준 디자인 가이드가 문제였다. 디자이너들이 만들었지만, 이게… 개발자랑 한 번도 협업을 해본 적이 없음 + 전사 백오피스 디자인 가이드라 아무래도 신경을 잘 쓰지 못한 부분들이 있었다.
색상을 만들 때 opacity로 색을 만든 경우가 종종 있음
이렇게 만들면 결과적으로 같은 색상처럼 보여도 실제로는 뒷배경에 따라 색상이 달라지는 문제
디자인 토큰의 변수 키 값이 통일되지 않음
Button에서 size의 키 값은 s, m, l이라면 Tooltip에서 size는 sm, md, lg 이런 식으로 키 값이 변해서 개발 시에 어떤 키 값을 따라가야 할지 파악하기 어려움
Variant가 정해지지 않는 UI들
어떤 UI들은 outlined까지 잘 정리되어 있는데, 어떤 UI는 정해지지 않은 variant들이 너무 많음
컨벤션이 맞지 않는 color name들primary-bg, primary-basic-bg 등등... 같은 색상을 나타내는 색상 key 값이지만 컨벤션이 맞지 않아 어떤 걸 써야 할지 난감
Figma 라이브러리 배포를 하지 않음
디자인팀 내부적으로 이유는 모르겠으나, Figma 라이브러리를 배포하지 않고 Figma 파일을 복제해서 각 팀별로 써야 했음(버전 관리나 유지보수에서 문제…)
시간이 충분했던 게 아니라서 앞선 문제는 FE 개발자들끼리 컨벤션으로 정하고, 확장성 있게 컨벤션을 정했다. 시니어 FE 개발자 분이 계셔서 이런 컨벤션을 정하는 것에 대해 크게 문제없이 넘어갈 수 있었다. (이래서 경험이…)
그리고 디자인팀과 여러 미팅을 통해 개선보다는 1차적으로 만들고 디자인팀에 피드백하는 방향으로 개발을 진행했다.
디자인 가이드에 있는 27개의 컴포넌트 + Storybook + 개발자 가이드(Nextra) + 개발 공식 문서를 약 30일(워킹데이로) 만에 완성했다. (FE 투입 2명)
빠르게 개발할 수 있었던 이유는 당연하게도 primitive UI를 개발하지 않고 스타일만 수정하면 되는 부분이었고, Monorepo를 통해서 Storybook, 개발자 가이드, 공식 문서에 활용하기도 좋았다. 컨벤션도 한 번 정해지면 이후에는 AI를 통해 찍어내듯이 개발을 할 수 있었다.
이후 새로운 서비스에는 우리가 만든 디자인 시스템을 적용할 수 있었고, 커스텀 UI가 생긴다거나 UI로 제공하기 애매한 Chart, Data Table, Text Editor 등… 우리 디자인 가이드에 맞춰 입맛대로 UI를 개발할 수 있었고, 개발 속도 또한 빨랐다.
우리는 더 이상 UI 개발에 고민을 하지 않아도 되기 때문이다.
실제로 이후 4개의 앱 개발에 디자인 시스템을 적용했고, 4개의 앱을 개발할 때도 워킹데이로 약 50일 만에 개발을 완료할 수 있었다. 3명의 개발자가 동시에 작업을 해도 UI 컨벤션 또한 일관성 있게 유지되었다.
물론 좋은 점만 있었던 건 아니다.
새로운 라이브러리에 대한 학습과 Headless 개념을 이해시키는 과정도 필요했다. 개발할 때도 합성 컴포넌트로 할지, 폴더 구조로 가져가야 할지, render 컴포넌트를 만들어야 할지… 정해야 할 게 생각보다 많았다.

회사에 미보고 프로젝트 중에서 우리와 같이 전사 디자인 시스템을 개발하고 있었던 팀이 있었다..(3개월 전부터 잠수함 개발을 하고 있던..) 심지어 전사 플랫폼의 코어에 있던 팀이라 명분 또한 그 팀에 있었다.
만약 우리가 만든 디자인 시스템을 전사 디자인 시스템으로 만들고 싶다면, 우리가 플랫폼 코어 쪽으로 인원을 재배치해야 하는 입장이었다..(이건 너무 최악)
그래서 그냥 전사 디자인 시스템이라는 타이틀은 그쪽 팀에 그냥 넘겼다.
다만 해당 팀은:
Primitive UI를 직접 개발하고
Open code 형식도 아니고
디자인 시스템에 대한 책임도 회사 오픈소스로 올려서 관리한다고 하길래…
나는 우리가 만든 디자인 시스템을 사용하는 걸로 방향을 잡았다.
만약 해당 팀에서 만든 UI가 새롭게 추가되거나 좋다면, 스타일 코드를 그대로 우리쪽으로 가져가 붙이면 되기 때문이다.
하지만 전사 디자인 시스템이라는 명분이 없어지고 본부 디자인 시스템이라는 명분밖에 없으니, 원래 하고자 했었던 MCP를 붙인다거나 하는 부분은 하지 못해 아쉽긴 하다.
다만 요즘에는 Figma MCP가 있으니, Cursor에서 새로운 UI에 대한 디자인 토큰을 Figma MCP로 받아와 우리 디자인 시스템에 맞춰 개발하면 5분이면 뚝딱하고 만들어서… MCP를 못 만든 게 그렇게 아쉽진 않다.
어쩌다보니 FE라면 한번쯤 은 겪어야하는 디자인시스템 개발을 성공적으로 마무리 할 수있었다. 좋은 경험도 했었고, 나쁜 경험도 했었고.. 여튼 끝!!
앞서 말한, 내가 선택한 기술과 방식이 무조건 정답이라고 말할 수는 없다.
환경과 상황은 모두 다르기에, 때에 따라 맞춰서 개발 방향을 정하는 게 정답이라 생각한다. 지금도 새로운 기술은 나오고, shadcn/ui가 최고라고 말할 수 있는 것도 아니기 때문에…
다만 기술을 선택한 이유는 확실하게 가져가야 한다.
근거 없이 “요즘에는 이게 좋대요~”, “어디 회사에서는 이렇게 쓴대요~”는 결국 똑같은 실수를 반복하게 될 거다.
내가 shadcn/ui를 선택한 이유 또한 그렇다.
이 글이 비슷한 고민을 하고 있는 누군가에게 작은 도움이라도 되길 바란다.