grep

Design

팀 개발 속도 높이기: 피그마 컴포넌트 코드 자동 변환 플러그인 제작기

황주희Julie(쥴리) / 파트너웹개발팀여기어때

2025년 9월 1일

원문에서 보기 ↗

안녕하세요, 여기어때컴퍼니 파트너웹개발팀 쥴리입니다.

저희 팀은 효율적인 개발 환경을 만들기 위해 꾸준히 개선하고, 새로운 방식을 도입하고 있습니다.

이 플러그인을 도입한 이후, Typography 컴포넌트를 작성하는 데 걸리는 시간이 30초에서 5초 미만으로 줄어드는 등 UI 개발 속도가 약 80% 향상되었습니다.

이번 글에서는 해당 플러그인을 만들게 된 배경과 구현 과정, 그리고 실제 도입 후의 변화에 대해 소개하려 합니다.

디자인을 코드로 옮길 때 겪은 문제들

디자인 시스템이 잘 갖추어져 있어도, 디자인을 실제 코드로 옮기려면 몇 단계의 수작업이 필요합니다.

디자인을 직접 코드로 옮기는 데 필요한 작업들

UI를 개발할 때마다 디자인 요소를 하나씩 선택해 스타일을 확인하고, 팀 컴포넌트 규칙에 맞춰 코드를 작성해야 합니다.

이 과정에서 스타일을 놓치거나 오타를 내는 경우가 종종 있었고, 무엇보다도 이런 반복적인 작업에 드는 시간이 아깝게 느껴졌습니다.

ㅤ

왜 플러그인을 직접 만들기로 했을까?

이 과정을 자동화하기 위해 다양한 방법을 시도해 보았습니다.

  1. 기존 피그마 플러그인 사용
  2. Figma Code Connect 기능 사용
  3. 직접 피그마 플러그인 제작

먼저, 피그마에서 요소를 선택하면 JSX 코드를 생성 해주는 기존 플러그인들을 테스트했습니다. 하지만 저희 팀만의 디자인 시스템 규칙을 반영하지 못해 결과물을 그대로 쓸 수 없었습니다.

다음으로는 Figma Code Connect 기능을 도입해 보려 했습니다.

Figma Code Connect

: 디자인과 코드 저장소를 연결해 코드 스니펫을 보여주는 기능

피그마에 정의된 디자인 속성과 실제 코드 간 네이밍 불일치, 구현 방식의 차이로 인해 유지보수 가능한 수준의 연결을 만들기는 어려웠습니다.

결국, 팀 환경에 최적화된 플러그인을 직접 만드는 것이 가장 현실적인 해결책이라고 판단했습니다.

클릭 한 번으로 변환되는 Auto Component 플러그인

이렇게 시작된 프로젝트의 목표는 명확했습니다.

“피그마에서 디자인 요소를 클릭하면, 우리 팀 규칙에 맞는 코드가 자동으로 나오도록 하자”

핵심은 개발자의 워크플로우를 방해하지 않는 것이었습니다.

이를 위해 3가지 목표를 설정하였습니다.

ㅤ

왜 Codegen Plugin API 였을까?

Plugins for Code Generation | Plugin API

Plugins in Dev Mode can extend Figma’s native code snippets to generate code for languages or frameworks that Figma…www.figma.com

이 요구사항을 가장 단순하게 충족한 방법이 바로 Figma Codegen Plugin API 였습니다.

이 장점 덕분에 초기 설계부터 Dev Mode 전용 플러그인으로 방향을 정했습니다.

ㅤ

Codegen Plugin API 실행 흐름

동작 과정은 의외로 단순합니다.

플러그인 동작 과정

실제 핸들러 코드는 다음과 같습니다.

// code.ts
figma.codegen.on("generate", async (event) => {
  const node = event.node; // 현재 선택된 노드
  const code = generateNodeCode(node); // Rule-Based 매핑 처리
return [
    {
      title: "Component Generator",
      language: "JAVASCRIPT",
      code,
    },
  ];
});

사용자가 노드를 선택하면, codegen.on("generate") 핸들러가 호출되고 해당 노드 정보가 전달됩니다.

이 핸들러는 단순히 선택된 노드를 받아 generateNodeCode에 넘기고, 반환된 JSX를 Inspect 패널에 전달하는 역할을 합니다.

여기서 핵심은 generateNodeCode가 어떤 로직으로 노드를 해석하고 JSX를 반환하느냐입니다. 이 함수가 팀 규칙을 반영해 UI를 "한 번의 클릭"으로 완성시키는 엔진입니다.

ㅤ

AS-IS vs TO-BE: 결과 비교

설명이 더 와닿도록 결과를 먼저 보겠습니다.

Auto Component Plugin 결과

이렇게 반복되는 스타일 확인과 수동 입력 과정이 사라지고, 클릭 한 번으로 디자인 시스템 규칙에 맞는 코드가 생성됩니다.

이제 generateNodeCode 내부에서 어떤 규칙을 적용해 이런 결과를 만들어내는지 살펴보겠습니다.

ㅤ

Rule-Based 매핑: 어떻게 구현했을까?

Auto Component 플러그인은 AI 기반 매핑이 아닌, 디자인 시스템 규칙을 코드화한 룰 베이스(rule-based) 방식으로 동작합니다.

노드 타입에 따라 분기하고, 자식(children)이 있으면 재귀적으로 호출해 전체 트리를 JSX로 변환합니다.

노드 타입에 따른 Rule-Based 매핑 흐름

ㅤ

1. TextNode → Typography

가장 먼저 처리한 건 Typography 매핑이었습니다.

피그마의 텍스트 속성은 fontSize, lineHeight, fontWeight, color처럼 쪼개져 내려오지만, 저희 디자인 시스템은 body2Medium, caption1Regular 같은 조합된 variant 와 textPrimary 같은 컬러 토큰으로 관리됩니다.

그래서

const color = await getFontColor(node);
const variant = getVariant(node); 
// 예: fontSize=14, lineHeight=20, fontWeight=500 → "body2LeadingMedium"

Mixed Style 처리

Mixed Style도 고려해야 했습니다. 한 문장 안에 Bold와 Regular가 섞인 경우, extractStyledChunks로 텍스트를 스타일 단위로 잘라 각각 <Typography>로 감쌌습니다.

또한, · 같은 특수문자는 &middot;로 변환해 코드 일관성을 유지했습니다.

Typography 변환 결과

ㅤ

2. InstanceNode → SvgIcon, Button, 기타 컴포넌트

Instance 노드는 네이밍 패턴을 기준으로 매핑했습니다.

SvgIcon 변환 결과

특히 IconButton은 자식 노드에서 실제 아이콘을 찾아 props로 붙여줘야 했습니다. 자식 노드를 재귀 탐색해 다음과 같이 변환했습니다.

IconButton 변환 결과

버튼 내부 텍스트도 별도로 처리했습니다. 아래처럼 순수 문자열만 들어가는 것이 올바른 형태라 버튼 내부 텍스트를 <Typography>로 감싸버리면 구조가 꼬여버리게 됩니다.

그래서 ctx.inButton 컨텍스트 플래그를 두어, 버튼 내부 텍스트인 경우에는 순수 문자열만 반환하도록 처리했습니다.

TextButton 반환 결과

BoxButton 반환 결과

ㅤ

3. FrameNode / ComponentNode → Stack, Block

FrameNode와 ComponentNode는 auto layout 여부에 따라 분기했습니다.

선택한 노드 속성을 얻어 방향(direction), 정렬(justifyContent, alignItems), 간격(gap), 패딩(pt, pr, pb, pl 등)까지 모두 반영하였습니다.

그리고 좌우/상하 패딩값이 같으면 px, py로 줄여 가독성을 높였습니다.

<Stack direction="row" gap={8} alignItems="center">
  <Typography variant="title1Medium">제목</Typography>
  <SvgIcon name="icn_close" />
</Stack>

ㅤ

4. 트리 전체 변환 (재귀 호출)

모든 매핑은 재귀적으로 동작합니다.

const children = await Promise.all(
  node.children.map((c) => generateNodeCode(c, ctx))
);

노드 안에는 또 다른 Frame, Instance, TextNode가 있고, 그 안에도 다시 자식이 있기 때문이죠.

const content = children.join("\n");
return `<Stack>${content}</Stack>`;

그리고 처음에는 이렇게 단순히 join으로 자식들을 이어 붙였습니다.

하지만 빈 문자열까지 포함되어, <Stack>\n\n<Text>..</Text>\n\n</Stack>처럼 코드가 지저분해졌습니다.

const content = children.filter(Boolean).join("\n");
return content
  ? `<Stack>\n${indent(content)}\n</Stack>`
  : `<Stack />`;

그래서 빈문자열은 필터링 하고, indent 유틸로 들여쓰기를 적용해 가독성 있는 JSX를 생성했습니다.

작은 차이지만, 결과 코드를 바로 붙여 넣을 수 있는 수준으로 만들기 위해 필수적인 작업이었습니다.

플러그인 도입 이후의 변화

사내 Dev Mode 전용 Auto Component 플러그인

플러그인을 적용한 뒤 변화는 명확했습니다.

무엇보다도 팀원들의 반응이 긍정적이었습니다.

“작업하기 편하다”

“속도가 확실히 빨라졌다”

“덕분에 입사 초반에 디자인 시스템을 익히기 쉬웠다.”

물론 단점도 있었습니다. 불필요한 컴포넌트가 생성되기도 했고, 모든 속성을 완벽히 반영하기는 어렵다는 한계도 분명 존재했습니다. 하지만 이건 계속 개선해 나가면 될 문제였습니다.

마치며

피그마에서 필요한 API를 제공해 주어서 생각보다 손쉽게 개발할 수 있었고, 팀의 작업 속도를 높일 수 있어 큰 보람을 느꼈습니다.

그리고 자동화는 단순히 시간을 줄여주는 것 이상으로, 개발자가 본질적인 문제 해결에 집중할 수 있는 환경을 만든다는 점을 다시 한번 체감했습니다.

마지막까지 읽어주셔서 감사합니다.

비슷한 고민을 하고 계신 분들께 조금이나마 도움이 되었길 바랍니다.