ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #2 하나의 디자인 파일 - 그리고 전파!
    Design System Library 2026. 4. 17. 13:02

    7onic 디자인 시스템은 JSON 파일 하나로 돌아간다

    7onic 디자인 시스템 전체를 움직이는 핵심은 JSON 파일 하나다.

    줄 수는 1,847줄.

    색상은 #6B21A8 같은 hex 값으로 들어 있고, spacing은 16 같은 숫자로 저장된다. border radius도 같은 방식이다. 애니메이션은 keyframe 객체 형태로 정의되어 있다.

    Figma Token Studio에서 토큰을 export 해본 사람이라면 익숙하게 느껴질 것이다.

    왜냐하면 정말 그 파일이 맞기 때문이다.

    파일 이름은:

    figma-tokens.json
     

    그리고 이 파일은 코드베이스 안에서 디자인 값이 직접 존재할 수 있는 유일한 장소다.

    나머지는 전부 자동 생성된다.

    명령어 한 번 실행하면 이 파일을 읽고, 약 2초 만에 배포용 파일 11개를 만들어낸다.

    색 하나 수정한다.
    스크립트를 실행한다.
    배포한다.

    끝.

    파이프라인 자체는 놀라울 정도로 단순하다.

    물론 여기까지 오는 과정은 전혀 단순하지 않았다.

     

    어떻게 파일 하나가 11개가 되었나???

    처음 들으면 이런 생각이 든다.

    아니, 토큰 파일 하나면 충분한 거 아닌가?

    나도 그렇게 생각했다.

    하지만 현실은 다르다.

    환경마다 원하는 출력 형태가 전부 다르기 때문이다.

    예를 들면:

    • Tailwind v3 프로젝트는 preset 파일이 필요하다.
    • Tailwind v4는 @theme 구조를 원한다.
    • 순수 CSS 프로젝트는 CSS 변수만 있으면 된다.
    • React 밖에서 쓰는 프로젝트는 TypeScript 타입만 필요할 수도 있다.
    • 어떤 팀은 내부 툴링용으로 raw JSON만 필요하다.

    소스는 하나인데, 사용자는 제각각이다.

    그래서 현재 파이프라인은 다음 결과물을 만든다.

    • css/variables.css
    • css/themes/light.css
    • css/themes/dark.css
    • css/all.css
    • tailwind/v3-preset.js
    • tailwind/v4-theme.css
    • tailwind/v4.css
    • js/index.js
    • js/index.mjs
    • types/index.d.ts
    • json/tokens.json

    대부분은 비교적 순조롭게 만들었다.

    하지만 정작~ 몇 개는 정말 ! 지금 생각해도 머리가 아플지경이다.

    bg-primary/50 이 모든 걸 망가뜨린 날

    초기 버전 파이프라인은 매우 순진했다.

    1. JSON 읽기
    2. 토큰 순회하기
    3. CSS 변수 생성
    4. Tailwind config 생성

    끝.

    아주 아름답게 단순했다.

    그러다 테스트로 이것을 써봤다.

     
    <div class="bg-primary/50">
     

    아무 일도 일어나지 않았다.


    왜 안 됐을까?

    Tailwind의 opacity modifier (/50)는 색상 채널값에 접근해서 alpha 값을 주입하는 방식으로 동작한다.

    hex 값이라면 문제없다.

    하지만 이런 값은 다르다.

     
    var(--color-primary)
     

    Tailwind 입장에서 CSS 변수는 그냥 문자열이다.

    안을 뜯어보고:

    • hex 값 읽고
    • RGB로 바꾸고
    • opacity 넣고

    같은 작업을 할 수 없다.

    즉, 너무 똑똑한 척하지만 실제로는 못 한다.


    그래서 색상을 두 번 배포하게 됐다

    결국 모든 색상 토큰을 두 가지 형태로 만들었다.

     
    --color-primary: #6B21A8;
    --color-primary-rgb: 107, 33, 168;
     

    그리고 Tailwind v3에서는 이렇게 사용한다.

     
    rgb(var(--color-primary-rgb) / <alpha-value>)
     

    그제서야 드디어 아래 클래스들이 정상 동작했다.

    • bg-primary/50
    • border-border/40
    • text-foreground/80

    즉, 모든 색상이 이제 두 번 출고된다.

    • 한 번은 hex
    • 한 번은 RGB 채널값

    완벽한가?

    솔직히 모르겠다.

    효과적인가?

    압도적으로 그렇다.

    Tailwind v4는 color-mix() 덕분에 훨씬 쉬워졌지만, v3는 나를 먼저 단련시켰다.


    다크모드: 나를 피말려 죽여가는 모드

    다크모드는 늘 이렇게 시작한다.

     
    :root = light
    .dark = dark
     

    그리고 <html>에 class만 토글한다.

    클래식하다.
    믿음직하다.
    Tailwind v3에서는 아주 잘 된다.

    그러다 Tailwind v4가 등장했다.

    철학이 달랐다.

     
    @media (prefers-color-scheme: dark)
     

    운영체제 설정을 따라가자는 방식이다.

    이것도 합리적이다.

    문제는 실제 사용자가 이런 말을 할 때다.

    내 OS는 dark인데, 사이트는 light로 보고 싶어요.

    그 순간부터 복잡해진다.


    최종적으로는 3중 전략이 되었다

    현재 시스템은 동시에 세 가지를 지원한다.

    1. 기본적으로 OS 설정 추종
    2. data-theme="dark" 강제 지정 지원
    3. 구형 .dark class 방식 호환

    그리고 가장 중요한 탈출구가 하나 있다.

     
    <html data-theme="light">
     

    이렇게 하면 OS가 dark여도 light 모드로 강제된다.

    지금 보면 간단해 보인다.

    하지만, 당시엔 전혀 아니었다. 진짜루!


    아무도 알려주지 않는 Tailwind v4 함정

    이건 배포 후 발견해서 더 아팠다.

    내가 쓴 코드는 이것이었다.

     
    @theme inline
     

    보기엔 멀쩡하다.

    하지만 실제로는 토큰 값을 utility class 안에 직접 박아 넣는다.

    원래 원했던 건:

     
    background-color: var(--color-primary);
     

    그런데 실제 결과는:

     
    background-color: #6B21A8;
     

    라이트 모드에서는 티가 안 난다.

    그러다 다크모드로 전환하면…

    아무것도 안 바뀐다.

    왜냐하면:

    • CSS 변수는 바뀔 수 있다.
    • 하드코딩된 hex 값은 바뀌지 않는다.

    다크모드는 요란하게 망가지지 않았다.

    조용하고 품위 있게 망가졌다.


    해결책은 단어 하나 삭제

    @theme
     

    끝.

    inline 제거.

    한 단어 차이지만 결과는 치명적으로 다르다.

    이제 이 교훈은 스크립트 주석과 설계 문서에 영구 보관 중이다.

    미래의 내가 또 같은 실수를 할 게 분명하기 때문이다.


    TypeScript 타입도 자동 생성된다

    파이프라인은 이런 선언도 만든다.

     
    export declare const colorPrimary: string;
    export declare const spacingMd: string;
     

    대부분의 경우 없어도 된다.

    하지만:

    • 차트 색상 연결
    • 런타임 테마 처리
    • 동적 설정 시스템
    • 코드 기반 토큰 참조

    이런 상황에서는 꽤 편하다.

    자동 생성이 되기 시작하면 추가 비용은 거의 0에 가깝다.


    진짜 중요한 건 기술 디테일이 아니다

    솔직히 말하면 위 내용은 재미있는 엔지니어링 잡학이다.

    하지만 핵심 가치는 따로 있다.


    Before

    • 디자인 값은 Figma에 있었다
    • 코드 값은 코드베이스 어딘가에 있었다
    • 둘을 맞추려면 사람이 계속 신경 써야 했다
    • 결국 사람은 졌다

    After

    • 값은 한 파일에만 있다
    • 나머지는 전부 생성된다
    • Drift는 구조적으로 불가능해진다

    끝이다.

    결국 내가 만든 제품은 이것이다

    11개 출력 파일도 아니고,
    RGB 채널 변수도 아니고,
    다크모드 전략도 아니다.

    내가 만든 진짜 제품은:

    디자인과 코드가 더 이상 현실을 두고 싸우지 않는 시스템

    그게 7onic이다.

     

     


     

    7onic은 디자인과 코드가 어긋나지 않도록 설계된 오픈소스 디자인 시스템입니다.
    무료로 사용할 수 있으며, **MIT License**로 제공됩니다.

    - 공식 사이트 & 인터랙티브 플레이그라운드: https://7onic.design
    - GitHub: 공개 레포 
    - 공식 영문 블로그
    - X 업데이트: @7onicHQ 

    GitHub Star는 큰 힘이 됩니다.

     

     

     

     

    7onic Design System

     

    7onic Design System

    7onic 디자인 시스템은 디자인과 코드의 불일치를 제로로. Figma 토큰을 단일 소스로, 디자이너가 직접 검증한 Radix UI 기반 React 컴포넌트. AI 협업 개발에 최적화된 오픈소스. npm install 또는 CLI 소스

    7onic.design

    글은 본인의 7onic 디자인 시스템 영문 원문 블로그에서 가져 왔습니다

     




     

    'Design System Library' 카테고리의 다른 글

    #4 Tailwind v4 - 고생의 시작  (0) 2026.04.17
    #3 혼자 만드는 디자인 시스템  (1) 2026.04.17
    #1 내가 7onic을 만든 이유  (0) 2026.04.17
7onic Blog.