[번역] 주말 만에 디자인 시스템 구축하기 (1인 개발자 및 소규모 팀을 위한 가이드)
Soshy·
원문: How to Build a Design System in a Weekend (For Solo Devs and Small Teams)
사이드 프로젝트를 시작한 지 6개월쯤 됐을 때, 저는 알면서도 계속 외면해 온 문제가 하나 있었습니다.
새 버튼이 필요할 때마다 스타일을 처음부터 다시 썼습니다. 새 카드 컴포넌트마다 이전 것과 패딩이 조금씩 달랐습니다. 회색 계열 색상은 #666, #6b6b6b, #707070... 수십 개의 파일에 제각각 흩어져 있었습니다. 제품 자체는 잘 동작했지만, 새 페이지를 만들 때마다 필요 이상으로 시간이 걸렸고, 매번 디자인 결정을 처음 내리는 것 같은 느낌을 지울 수가 없었습니다.
해결책은 간단했습니다. 실제로 쓰기로 결심한 변수들을 모아둔 CSS 파일 하나면 충분했습니다.
이것이 바로 1인 개발자나 소규모 팀을 위한 디자인 시스템의 핵심입니다. Figma 토큰을 CI 파이프라인에 동기화하는 것도 아니고, 200개의 컴포넌트를 문서화한 Storybook 인스턴스도 아닙니다. 프로젝트의 모든 컴포넌트가 실제로 참조하는, 한 곳에 정리된 결정들의 집합이면 됩니다.
주말 동안 이를 만드는 방법을 소개합니다.
왜 대부분의 1인 개발자는 건너뛰는가 (그리고 나중에 후회하는가)
가장 흔한 이유는 시간입니다. 디자인 시스템은 인프라 작업처럼 느껴지고, 프로젝트가 "충분히 커졌을 때" 손댈 일처럼 보입니다. 그래서 일단 빠르게 출시하고, 즉흥적인 결정을 내리고, 다음으로 넘어갑니다.
그 대가는 조용히 쌓입니다. Sparkbox의 연구 보고서에 따르면, 디자인 시스템을 갖춘 팀은 그렇지 않은 팀보다 폼(form) 개발에 47% 적은 시간을 쓴다고 합니다. 이 격차는 복리처럼 불어납니다. 시스템 없이 만드는 컴포넌트마다 조금씩 다른 선례를 남기게 되고, 6개월 후에는 버튼 변형이 열다섯 가지나 생겼지만 어떤 상황에 어떤 버튼을 써야 하는지 명확한 기준이 없는 상태가 됩니다.
또 다른 대가는 측정하기가 더 어렵습니다. 바로 결정 피로(decision fatigue)입니다. 시스템이 없으면 새 UI 요소를 만들 때마다 같은 질문에 다시 답해야 합니다. 패딩은 얼마나 줄까? 폰트 크기는? 테두리 반지름은? 디자인 시스템은 이 질문들에 한 번만 답합니다. 그 이후로는 결정 대신 구현에만 집중할 수 있습니다.
주말 하루 이틀의 투자는 다음 기능을 출시할 때 이미 본전을 뽑습니다.
최소 기능 디자인 시스템
처음부터 거창하게 시작할 필요는 없습니다. 1인 개발자나 소규모 팀에게 필요한 디자인 시스템은 정확히 네 가지로 이루어집니다.
디자인 토큰 — 원시 값들입니다. 색상, 여백, 테두리 반지름, 폰트 크기처럼 다른 모든 것이 참조하는 기본 단위입니다.
타이포그래피 스케일 — 제목, 본문, 캡션, 레이블에 사용할 크기와 굵기를 미리 정해둔 집합입니다. 선택지가 무한해서는 안 되고, 고정된 집합이어야 합니다.
여백 스케일 — 패딩, 마진, 간격에 일관되게 적용할 리듬입니다. 가장 일반적인 방식은 8px를 기본 단위로 4, 8, 16, 24, 32, 48, 64처럼 정해진 스케일을 사용하는 것입니다.
컴포넌트 라이브러리 — 버튼, 폼, 카드부터 시작합니다. 전부 만들 필요는 없고, 어떤 프로젝트에서든 반드시 쓰게 되는 이 세 가지만 먼저 만들면 됩니다.
이게 전부입니다. 나머지는 실제로 필요해질 때 추가해도 늦지 않습니다.

CSS 커스텀 프로퍼티를 근간으로
시작할 때 Style Dictionary나 Theo 같은 빌드 툴링은 필요 없습니다. 1인 프로젝트나 소규모 팀에게는 잘 구조화된 CSS 커스텀 프로퍼티 파일 하나면 충분합니다.
실제 토큰 파일은 이런 모습입니다.
/* tokens.css */
:root {
/* Colors — primitives */
--blue-500: #2563eb;
--blue-600: #1d4ed8;
--gray-100: #f3f4f6;
--gray-700: #374151;
--gray-900: #111827;
--red-500: #ef4444;
--white: #ffffff;
/* Colors — semantic */
--color-primary: var(--blue-500);
--color-primary-hover: var(--blue-600);
--color-text: var(--gray-900);
--color-text-muted: var(--gray-700);
--color-surface: var(--gray-100);
--color-error: var(--red-500);
/* Spacing */
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-12: 3rem; /* 48px */
/* Typography */
--font-size-sm: 0.875rem;
--font-size-base: 1rem;
--font-size-lg: 1.125rem;
--font-size-xl: 1.25rem;
--font-size-2xl: 1.5rem;
--font-size-3xl: 1.875rem;
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-bold: 700;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
/* Border */
--radius-sm: 4px;
--radius-md: 6px;
--radius-lg: 8px;
--radius-full: 9999px;
}
처음부터 두 레이어로 나누는 방식 — 원시 값(--blue-500)과 시맨틱 토큰(--color-primary) — 을 도입해 두는 것이 좋습니다. design.dev의 2025 디자인 시스템 가이드에 따르면, 원시 값과 시맨틱 토큰을 분리해야 나중에 테마 적용이 가능해진다고 합니다. 다크 모드를 추가하고 싶을 때 시맨틱 레이어만 변경하면 됩니다. 원시 값은 그대로고, 컴포넌트도 그대로이며, --color-primary가 가리키는 값만 바꾸면 끝납니다.
CSS 커스텀 프로퍼티는 런타임에서 동작하기 때문에 빌드 단계 없이 업데이트되고, JavaScript로도 수정할 수 있습니다. 테마 전환을 지원하고, 사용자 설정에 반응하며, 컴포넌트 트리를 통해 자연스럽게 상속됩니다. 브라우저가 보기 전에 컴파일되어 사라지는 Sass 변수로는 불가능한 기능들입니다.
이 파일을 메인 스타일시트 상단에서 임포트해 두면, 이후 작성하는 모든 컴포넌트에서 즉시 모든 토큰에 접근할 수 있습니다.

무엇을 먼저 만들 것인가: 버튼, 폼, 카드 순서로
버튼을 먼저 만드세요. 버튼은 어떤 프로젝트에나 있고, 어떤 UI에서도 가장 자주 쓰이는 컴포넌트입니다. 상태도 가장 많습니다. 기본, 호버, 포커스, 활성, 비활성, 로딩까지. 버튼을 제대로 만들려면 색상 토큰, 테두리 반지름, 여백 스케일, 포커스 링 스타일을 한꺼번에 결정해야 합니다. 이 과정이 곧 나머지 컴포넌트의 시각적 언어를 정하는 작업이 됩니다.
.btn {
display: inline-flex;
align-items: center;
gap: var(--space-2);
padding: var(--space-2) var(--space-4);
font-size: var(--font-size-base);
font-weight: var(--font-weight-medium);
border-radius: var(--radius-md);
border: none;
cursor: pointer;
transition: background-color 0.15s ease;
}
.btn-primary {
background: var(--color-primary);
color: var(--white);
}
.btn-primary:hover {
background: var(--color-primary-hover);
}
.btn-primary:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
.btn-primary:disabled {
opacity: 0.5;
cursor: not-allowed;
}
모든 값이 토큰으로 선언되어 있습니다. 하드코딩된 색상도, 매직 넘버도 없습니다. 브랜드 색상이 바뀌면 tokens.css에서 한 줄만 수정하면 버튼이 모든 곳에서 한 번에 업데이트됩니다.
폼을 두 번째로 만드세요. 시각적 불일치가 사용자 마찰로 가장 직결되는 곳이 폼입니다. 입력 필드, 레이블, 에러 상태, 도움말 텍스트는 서로 일관되게 느껴져야 합니다. 버튼을 먼저 만든 덕분에 여백 스케일과 테두리 반지름 규칙이 이미 정해져 있고, 폼 컴포넌트는 자연스럽게 그 위에 쌓입니다.
카드를 세 번째로 만드세요. 카드는 가장 범용적인 컨테이너 패턴입니다. 버튼을 포함하고, 때로는 폼 요소도 담기 때문에 이 두 컴포넌트를 만든 이후에 작업해야 합니다. 카드는 또한 서피스 색상과 그림자 규칙을 확립하며, 이 결정이 시스템 전체에 영향을 줍니다.

미래의 나도 실제로 쓸 수 있도록 문서화하기
문서화는 1인 개발자가 가장 자주 건너뛰는 단계입니다. 그러다 6개월 후에 "왜 --radius-md를 6px로 했더라?", "컴포넌트 패딩이랑 레이아웃 패딩 중 어떤 값을 써야 하지?" 같은 질문에 스스로 막히게 됩니다.
실제로 사용하게 되는 최소한의 문서는 Storybook 인스턴스가 아닙니다. tokens.css를 임포트하고 모든 토큰과 컴포넌트를 시각적으로 렌더링하는 단일 HTML 파일, design-system.html 이면 충분합니다. 프레임워크도 필요 없습니다. 브라우저에서 열면 모든 것이 어떻게 생겼고 뭐라고 불러야 하는지 바로 확인할 수 있는 페이지면 됩니다.
다음 섹션들로 구성하세요.
색상 — 모든 시맨틱 토큰을 색상 견본으로 표시하고, 아래에 토큰 이름과 현재 값을 표기합니다. 작업 중에 뮤트된 텍스트 색상 이름이 기억나지 않을 때, 이 페이지를 열어 확인하고 바로 복사할 수 있습니다.
타이포그래피 — 각 크기 토큰을 해당 크기의 실제 텍스트로 표시합니다. --font-weight-bold의 --font-size-3xl로 표현된 "Heading 1", --font-weight-normal의 --font-size-base로 표현된 "Body"처럼요. rem 값 목록을 읽는 것보다 눈으로 확인하는 게 훨씬 빠릅니다.
여백 — 각 여백 값을 해당 너비나 높이의 색상 막대로 시각화합니다. 8px 기본 단위 시스템은 리듬을 눈으로 확인할 수 있어야 직관적으로 와닿습니다.
컴포넌트 — 각 컴포넌트를 모든 상태와 함께 한 곳에 표시합니다. 버튼은 기본·호버·비활성, 입력은 빈 상태·포커스·에러, 카드는 기본 상태로.
이 파일이 여러분의 참고 문서가 됩니다. Figma 파일을 열 때처럼 — 새로운 결정을 내리기 위해서가 아니라 이미 내린 결정을 확인하기 위해 — 이 페이지를 열게 됩니다.
툴링을 도입할 시점
잘 구조화된 CSS 파일이 올바른 출발점입니다. 더 나아갈 시점은 다음과 같습니다.
Style Dictionary는 웹, iOS, Android, 이메일 등 여러 플랫폼에서 토큰을 공유해야 할 때 도입할 가치가 있습니다. JSON 토큰 정의를 받아 플랫폼별 포맷으로 변환해줍니다. CSS 커스텀 프로퍼티, Sass 변수, Swift 에셋 카탈로그, Android XML 등을 각각 내보낼 수 있습니다. 1인 웹 프로젝트에는 과할 수 있지만, 웹 앱과 React Native 앱을 동시에 운영한다면 설정에 들인 시간이 금방 본전을 찾습니다.
Theo(Salesforce 제작)는 Style Dictionary와 유사하게 동작하며 설정 문법이 약간 더 단순합니다. 2025년 기준으로 활발하게 유지 관리되지는 않지만, 일찍 도입한 팀이라면 굳이 교체할 필요는 없습니다.
대부분의 1인 프로젝트와 소규모 팀에게는 잘 구조화된 CSS 파일 하나가 정답입니다. Specify의 2024 디자인 시스템 현황 보고서에 따르면, 성숙한 디자인 시스템의 74%가 토큰을 디자인 결정을 배포하는 주요 수단으로 사용한다고 합니다. 하지만 토큰이 어떤 포맷으로 존재하느냐보다, 실제로 일관되게 사용하는 규율이 훨씬 더 중요합니다.
툴링은 부차적인 문제입니다. 팀의 절반이 무시하는 JSON 파이프라인은 모두가 실제로 임포트하고 참조하는 CSS 파일보다 못합니다.

주말 계획
토요일 오전 (2~3시간): tokens.css를 만드세요. 색상 원시 값과 시맨틱 토큰, 여백 스케일, 타이포그래피 스케일을 정의하세요. 이것으로 확정짓는 겁니다. 이후로는 하드코딩된 값은 쓰지 않습니다.
토요일 오후 (3~4시간): 버튼 컴포넌트를 만드세요. 모든 상태를, 모든 값은 토큰으로.
일요일 오전 (2~3시간): 폼 컴포넌트를 만드세요. 입력, 레이블, 에러 상태, 도움말 텍스트.
일요일 오후 (2시간): 카드 컴포넌트를 만드세요. design-system.html을 시작하세요. 지금은 색상과 타이포그래피만.
일요일 저녁 (1시간): design-system.html에 컴포넌트를 추가하세요. 전부 커밋하세요. 완성입니다.
이게 전부입니다. 이제 이후에 만드는 모든 기능에서 시간을 아껴주는 디자인 시스템이 생겼습니다. 정교해서가 아니라, 일관되기 때문입니다.