hamen/material-3-skill · 제작 Ivan Morgillo(저작권자 표기는 CWTI Ltd) · 라이선스 MIT · 스킬 버전 1.1.1(2026-06-29 릴리스) · 최신 커밋 14385f2(2026-07-16) · 마크다운 9개·JSON 2개·YAML 1개·셸 1개, 소스코드 언어 없음 · GitHub Actions 워크플로 없음, 로컬 셸 CI만 존재)
material-3-skill은 소프트웨어가 아니라 "지식 패키지"다. 구글이 공개한 Material Design 3 디자인 시스템 — 색 토큰, 30개 이상의 컴포넌트, 반응형 레이아웃, 다이내믹 컬러 테마 — 을 AI 코딩 에이전트가 정확히 따라 만들 수 있도록, 그 규칙을 SKILL.md와 6개의 references/*.md 파일로 정리해 둔 것이다.
이 저장소가 하는 일은 정확히 이것이다: 사용자가 에이전트에게 "머티리얼 디자인으로 로그인 폼 만들어줘"라고 하면, 에이전트가 이 스킬을 읽고 MaterialTheme.colorScheme.primary 같은 정확한 토큰 이름과 OutlinedTextField 같은 정확한 컴포넌트 API를 써서 코드를 생성하게 만드는 것. 즉 "에이전트의 배경지식을 대신 조사해 주는" 역할이다.
AI 코딩 에이전트는 이미 요리(코드 생성)를 할 줄 아는 로봇 셰프다. 하지만 "머티리얼 디자인 3"라는 특정 요리법의 세세한 계량(정확한 dp 값, 토큰 이름, 컴포넌트 5종류의 우선순위)까지 다 외우고 있진 않다.
material-3-skill은 그 로봇 손에 정확한 레시피 카드(SKILL.md)를 쥐여준다. 로봇은 여전히 스스로 요리하지만, 카드 덕분에 "필터 칩과 어시스트 칩을 헷갈리는" 실수를 줄인다.
SKILL.md + references/)으로 묶어둔 파일 뭉치. 에이전트가 실행하는 프로그램이 아니라, 에이전트가 "읽고 따르는" 문서다.2025~2026년 사이 Claude Code·Codex·Cursor 같은 코딩 에이전트가 UI 코드까지 통째로 생성하는 게 당연해지면서, "에이전트가 만든 UI가 특정 디자인 시스템을 정확히 따르게 하는 법"이 새로운 문제로 떠올랐다. material-3-skill은 이 틈을 파고든 사례다.
LLM은 학습 데이터에 있던 Material Design 지식을 어느 정도 갖고 있지만, 토큰 이름·컴포넌트 우선순위·최신 스펙 변경(예: 2026년 I/O에서 발표된 Expressive 레이아웃) 같은 세부는 뒤섞이거나 낡아 있기 쉽다. 사람이 "정답 레퍼런스"를 미리 정리해 컨텍스트로 넣어주면, 에이전트가 즉흥적으로 지어내는 대신 그 문서를 인용하게 된다.
Claude Code의 /plugin marketplace·npx skills 같은 배포 채널이 자리잡으며, 이런 지식 패키지를 한 줄 명령으로 설치할 수 있게 됐다. material-3-skill은 이 흐름에 올라탄 초기 사례 중 하나로, README에 실제로 "Claude Code에 설치가 안 됐다"는 사용자 이슈(#8)를 반영해 마켓플레이스 매니페스트 구조를 통째로 바꾼 이력(v1.1.1)이 남아 있다 — 스킬 배포 방식 자체가 아직 정착 중이라는 방증이다.
이 스킬은 "모든 플랫폼을 동등하게 다룬다"고 말하지 않는다. Jetpack Compose를 1순위, Flutter를 2순위, 웹(@material/web)을 "유지보수 모드라 제한적"이라고 3순위로 명시한다. 이런 솔직한 우선순위 선언이 "그럴듯하지만 부정확한" 범용 가이드보다 실무에서 신뢰를 얻는다.
Claude Code의 에이전트 스킬 생태계에는 코드 이해·테스트·문서 작성 등 다양한 스킬이 쏟아지고 있다. material-3-skill은 그중에서도 "특정 디자인 시스템 하나를 정확히" 다루는 좁고 깊은 스킬의 전형이다. 폭넓은 범용 스킬이 아니라, "머티리얼 디자인 3"라는 한 주제에 집중해 정확도를 높이는 전략을 취한다.
디자인 시스템 없이 에이전트에게 UI를 맡기면 흔히 벌어지는 일: 색을 #6750A4 같은 하드코딩된 값으로 박아 넣거나, MD2(구버전)와 MD3(신버전) 컴포넌트를 섞어 쓰거나, 다크모드·접근성 대비를 빠뜨린다. 매번 사람이 리뷰하며 이런 실수를 잡아내야 했다.
material-3-skill은 이 문제를 사전 예방(생성 단계에서 정확한 규칙 주입)과 사후 점검(감사 모드) 두 갈래로 해결한다. SKILL.md의 "Anti-Patterns" 절이 흔한 실수 목록을 명시하고, audit 인자로 호출하면 10개 카테고리(색 토큰·타이포·형태·고도감·컴포넌트·레이아웃·내비게이션·모션·접근성·테마)를 0~10점으로 채점하는 MD3 준수도 감사 리포트를 만들어낸다.
건축에 비유하면 이 스킬은 "건축 법규 체크리스트를 든 감리사"다. 설계도(코드)를 직접 그리진 않지만, 그 설계도가 법규(디자인 스펙)를 지켰는지 조목조목 짚어준다. "여기 계단 폭이 규정보다 좁습니다"처럼, "여기 outline을 구분선에 썼는데 outline-variant를 써야 합니다"라고 지적하는 식이다.
/material-3 audit [경로 또는 URL]로 호출하면 색 토큰·타이포그래피·형태·고도감·컴포넌트·레이아웃·내비게이션·모션·접근성·테마 10개 항목을 채점해 "치명적 문제 → 경고 → 통과" 순으로 정리된 보고서를 만든다.
저장소를 통째로 훑으면 파일 수가 놀랍도록 적다. .git을 제외하면 총 12개 파일뿐이고, 그중 실행 가능한 프로그램 로직은 하나도 없다. 아래는 실제 디렉터리 구조다.
구조가 말해주는 것은 하나다. "매니페스트가 두 곳(①②)에 나뉘어 있다"는 점이 이 레포의 역사에서 가장 중요한 사건이었다. 처음엔 SKILL.md가 루트에 있었지만(v1.0.0 이전), Claude Code 플러그인 마켓플레이스로 설치하려면 루트에 마켓플레이스 선언(①)과, 실제 스킬이 있는 하위 폴더에 플러그인 선언(②)이 따로 필요하다는 걸 뒤늦게 알게 되며 지금 구조로 바뀌었다(자세한 사연은 9절 참고).
이 스킬의 진짜 설계는 코드가 아니라 "에이전트가 헷갈리지 않게 지식을 배치하는 방식"에 있다. skills/material-3/SKILL.md 하나를 뜯어보면 네 가지 설계 패턴이 겹겹이 쌓여 있다.
SKILL.md는 본문보다 먼저 "지금 뭘 만들려고 하는가"를 묻는 결정 트리를 배치한다. "전체 앱 스캐폴드 → references/layout-and-responsive.md", "단일 컴포넌트 → references/component-catalog.md"처럼, 목적별로 어느 참고 문서를 펴야 하는지를 먼저 라우팅한다. 이는 컨텍스트 창이 제한된 에이전트가 3,357줄짜리 참고자료 전체를 다 읽지 않고도 필요한 부분만 골라 읽게 만드는 핵심 장치다.
병원의 "안내 데스크"와 같다. 환자(에이전트)가 "배가 아파요"라고 하면 안내 데스크(결정 트리)가 "그럼 내과로 가세요"라고 바로 알려준다. 병원 전체 진료과(레퍼런스 6개 파일)를 처음부터 끝까지 다 돌아볼 필요가 없다.
SKILL.md의 "Decision Tree"·"Design Token System"·"Component Quick Reference"·"M3 Expressive" 절 전부에 "Jetpack Compose(주력) → Flutter(보조) → Web(제한적, 유지보수 모드)" 순서가 똑같이 반복된다. 예를 들어 M3 Expressive 표에서는 플랫폼별 지원 여부를 한 줄씩 명시한다.
| Capability | Compose | Flutter | Web (@material/web) |
|-----------------------------|---------------------|--------------------|---------------------------|
| Spring / motion physics | 지원 (MotionScheme) | Flutter 버전에 따라 다름 | 미지원 — easing/duration로 대체 |
| Shape morphing | 지원 (Compose-first) | 문서 확인 필요 | 미지원 (@material/web) |
CONTRIBUTING.md는 이 위계를 "뒤집지 말 것(do not invert)"이라는 명시적 규칙으로 못박아 두었다. 어떤 새 예제를 추가하든 기본값은 Compose다. 이 "일관된 반복"이야말로 LLM이 실수로 순서를 뒤바꾸는 것을 막는 설계다.
SKILL.md의 "Anti-Patterns" 절은 긍정 지시보다 부정 지시가 더 효과적인 경우를 정면으로 활용한다. "MD2와 MD3 라이브러리를 섞지 마라", "색을 하드코딩하지 마라, 항상 var(--md-sys-color-*)를 써라", "outline을 구분선에 쓰지 마라(구분선은 outline-variant)"처럼 구체적 실수를 나열한다. 이렇게 "흔한 실수 패턴"을 미리 박아두면, 에이전트가 학습 데이터에서 우연히 섞어 배운 낡은 습관을 억제하는 효과가 있다.
audit 모드는 단순히 "점검해봐"라고 지시하지 않는다. 10개 카테고리 채점표, 점수 구간별 상태(pass 7+ / warn 4~6 / fail 0~3), 그리고 출력해야 할 마크다운 리포트 템플릿 자체를 SKILL.md 안에 통째로 박아 넣었다. 심지어 웹 대상 정적 분석을 위한 grep 예시(grep -rn '#[0-9a-fA-F]\{3,8\}' --include='*.css')까지 준다.
많은 사람이 오해하는 지점: audit는 실제로 코드를 실행해 점수를 매기는 스캐너가 아니다. SKILL.md에 적힌 절차를 에이전트 자신이 읽고, 직접 소스를 열어보고, 스스로 판단해 리포트 형식에 맞춰 답변을 생성하는 것이다. 즉 채점의 정확도는 스킬이 아니라 그 순간 에이전트의 코드 이해력에 달려 있다.
CONTRIBUTING.md에 성문화돼 있다.md.sys 네임스페이스를 쓰며, 웹에서는 --md-sys-color-primary 같은 CSS 커스텀 프로퍼티로, Compose에서는 MaterialTheme.colorScheme.primary로 매핑된다.
이 저장소가 기동시키는 런타임은 없다. "기술 스택"이라 부를 수 있는 건 딱 두 층이다: ① 스킬이 설명하는 대상(Jetpack Compose, Flutter, @material/web)과 ② 스킬 자체를 검증하는 도구(jq, bash, 선택적으로 claude CLI)다. 이 둘을 헷갈리면 "이 레포를 어떻게 빌드하나요?"라는 질문 자체가 성립하지 않는다는 걸 놓치게 된다.
| 층 | 구성 요소 | 버전 진실원(source of truth) |
|---|---|---|
| 스킬이 설명하는 대상 ① | Jetpack Compose Material3 (androidx.compose.material3) | SKILL.md 본문 — "Primary" 명시. 구체적 BOM 버전은 명시하지 않고 "당신의 BOM에 맞춰 확인하라"고 안내 |
Flutter (useMaterial3: true) | SKILL.md "Secondary" — Flutter Material 문서 참조 권장 | |
@material/web | SKILL.md/README에서 "유지보수 모드"라고 반복 명시. 설치 예시는 npm install @material/web | |
| 스킬 자체 검증 도구 ② | jq | bin/ci가 jq -e .로 두 JSON 매니페스트 문법을 검증. 없으면 스크립트가 즉시 실패 |
bash | bin/ci·tests/plugin_layout_test.sh 둘 다 #!/usr/bin/env bash | |
claude CLI (선택) | 있을 때만 claude plugin validate --strict로 매니페스트 스키마까지 검사. 없으면 이 단계는 건너뜀 |
버전의 "진실원(source of truth)"은 딱 하나, skills/material-3/.claude-plugin/plugin.json의 "version": "1.1.1"이다. README의 "What's new" 절 버전 번호와 일치하는지가 곧 이 스킬의 배포 상태를 나타낸다. 루트의 .claude-plugin/marketplace.json에는 자체 버전 필드가 없고, 대신 plugins[0].source가 skills/material-3 경로를 가리키는 방식으로 실제 플러그인 매니페스트에 위임한다.
plugin.json은 "이 스킬이 무엇인지"(이름·버전·라이선스)를 설명하고, marketplace.json은 "이 저장소에 어떤 플러그인들이 있고 각각 어디에 있는지"(경로 매핑)를 설명한다. Claude Code는 먼저 마켓플레이스를 추가한 뒤, 그 안의 특정 플러그인을 설치하는 2단계 흐름을 쓴다.| 경로 | 명령 | 비고 |
|---|---|---|
권장: npx skills | npx --yes skills add hamen/material-3-skill --skill material-3 -y | Codex·Claude Code·Cursor 등 여러 에이전트에 공통으로 통하는 표준 설치 경로라고 README가 명시 |
| Claude Code 플러그인 | /plugin marketplace add hamen/material-3-skill/plugin install material-3@material-3-skill | 대화형 세션 안에서 실행. 셸에서는 claude plugin marketplace add … / claude plugin install … |
| 수동/Codex | git clone 후 ln -s $(pwd)/skills/material-3 ~/.codex/skills/material-3 | SKILL.md를 읽을 수 있는 아무 에이전트에나 심링크로 연결 가능 |
요구사항은 사실상 없다. 서버도, 데이터베이스도, 빌드 단계도 필요 없다 — 마크다운 파일을 에이전트가 읽을 수 있는 위치에 두기만 하면 끝이다. 다만 "이 스킬이 설명하는 대상"을 실제로 만들려면 각 플랫폼의 개발 환경(Android Studio + Kotlin/Compose BOM, Flutter SDK, 또는 Node + @material/web npm 패키지)이 별도로 필요하다 — 이건 스킬이 아니라 그 아래 실제 개발 스택의 요구사항이다.
v1.1.1 릴리스 노트가 스스로 인정하듯, 과거 실패 원인은 복잡한 의존성이 아니라 "매니페스트가 있어야 할 위치를 잘못 알았던 것"이었다. 설치가 안 될 때는 서버 로그를 뒤지기보다, skills/material-3/.claude-plugin/plugin.json이 실제로 존재하는지부터 확인하는 게 이 종류 레포의 디버깅 순서다.
설치 후 사용법은 SKILL.md 맨 위 argument-hint: "[component|theme|layout|scaffold|audit] [description or URL]"에 그대로 정의돼 있다. 즉 이 스킬은 네 가지 진입점을 갖는다.
/material-3 component 이메일과 비밀번호 필드가 있는 로그인 폼 만들어줘
→ 에이전트가 결정 트리에서 "Single component"를 찾아
references/component-catalog.md § Input Components 를 읽고
<md-outlined-text-field> 또는 Compose OutlinedTextField 로 구현
/material-3 theme 시드 컬러 #1A73E8 로 테마 생성해줘
→ references/theming-and-dynamic-color.md 를 읽고
ColorScheme.fromSeed() (Flutter) 또는
dynamicLightColorScheme()/lightColorScheme() (Compose) 로 분기
/material-3 scaffold 내비게이션이 있는 반응형 앱 셸 만들어줘
→ references/layout-and-responsive.md + navigation-patterns.md 를
함께 읽어 창 크기 클래스(window size class) 기반 스캐폴드 생성
/material-3 audit ./src 또는 https://example.com
→ 10개 카테고리 채점 → 치명적 문제 → 경고 → 통과 → 우선순위별 수정안
순서의 마크다운 리포트를 생성
중요한 건 이 네 모드가 서로 다른 프로그램이 아니라, 같은 SKILL.md 안에서 "지금 사용자가 무엇을 원하는지"에 따라 에이전트가 결정 트리를 타고 다른 참고 문서로 갈라지는 것뿐이라는 점이다. 실행 파일이나 API 엔드포인트는 존재하지 않는다.
깃허브에서 트렌딩에 오른 레포는 보통 npm start나 docker run 같은 걸로 뭔가가 돌아간다. 이 레포는 다르다. 실행할 진입점 자체가 없다. 파일을 클론해서 bin/ci를 돌려봐도 "매니페스트 문법이 맞는지 검증"만 할 뿐, 앱은 뜨지 않는다. 이 스킬의 유일한 "실행"은 AI 에이전트가 SKILL.md를 컨텍스트로 읽어들이는 순간이다.
README의 "What's new" 절이 실제로 증언한다: v1.0.0 때는 문서화된 claude plugin install github:hamen/material-3-skill 명령이 한 번도 작동하지 않았다. 이유는 Claude Code가 요구하는 게 "루트의 마켓플레이스 선언 + 하위 폴더의 플러그인 선언"이라는 이중 구조였는데, 초기엔 플러그인 매니페스트만 루트에 두었기 때문이다. v1.1.1에서 .claude-plugin/marketplace.json(루트)과 skills/material-3/.claude-plugin/plugin.json(하위)으로 분리하고 나서야 고쳐졌다. tests/plugin_layout_test.sh는 정확히 이 재발을 막기 위한 회귀 테스트다 — expect_absent ".claude-plugin/plugin.json"(루트에 있으면 안 됨)과 expect_absent "SKILL.md"(루트에 있으면 안 됨) 같은 항목이 그 증거다.
.github/ 폴더에는 FUNDING.yml 하나뿐, GitHub Actions 워크플로가 없다. 즉 PR을 올려도 bin/ci가 자동으로 실행되지 않는다. 이름과 달리 이건 "기여자가 커밋 전에 수동으로 돌려야 하는 로컬 검증 스크립트"에 가깝다. 실제 지속적 통합(자동 트리거)을 기대하면 착각이다.
README가 스스로 밝히듯 이 스킬의 내용은 "공식 문서 + 모델 학습 데이터에서 증류(distillation)"한 것이다. plugin.json의 1.1.1이라는 버전 번호는 "매니페스트 구조가 언제 바뀌었는가"를 보여줄 뿐, 그 안의 토큰 값·컴포넌트 스펙이 구글의 최신 사양과 100% 일치한다는 보증은 아니다. README는 "Web 섹션은 뒤처질 수 있으니 material-web 공식 저장소로 재검증하라"고 스스로 경고한다.
| 방식 | 장점 | 단점 |
|---|---|---|
| 공식 문서(m3.material.io)를 매번 직접 프롬프트에 붙여넣기 | 항상 최신, 왜곡 없음 | m3.material.io는 JS로 렌더링되는 SPA라 매번 브라우저 자동화 없이는 긁기 어렵고, 매번 사람이 반복 작업해야 함 |
| 이 스킬(material-3-skill) 설치 | 결정 트리·안티패턴·감사 절차까지 구조화돼 한 번 설치로 재사용, Compose 우선순위가 명확 | 스냅샷이라 스펙이 바뀌면 뒤처질 수 있음. 유지보수자 1인 개인 프로젝트라 갱신 속도가 구글 공식 문서보다 느릴 수 있음 |
| 범용 디자인 시스템 감사 도구(예: Storybook 애드온, 자체 린터) | 실제로 코드를 실행해 기계적으로 검사 — 사람 개입 없이 CI에 통합 가능 | Material 3 전용 규칙(토큰 페어링, Expressive 플랫폼별 지원표 등)까지 세세히 알진 못함. 이 스킬은 "실행되는 린터"가 아니라 "에이전트가 읽는 지식"이라 결이 다름 |
| 다른 범용 프론트엔드 디자인 스킬(예: frontend-design류) | 디자인 시스템에 얽매이지 않는 자유로운 창작 방향 제시 | MD3처럼 엄격한 토큰·컴포넌트 규칙을 따라야 하는 작업에는 오히려 방해(SKILL.md 자체가 "Roboto를 피하라는 frontend-design 규칙은 MD3에서 적용 안 됨"이라고 명시적으로 충돌을 해소해 둠) |
결론적으로 이 스킬의 자리는 "Material Design 3를 반복적으로, 정확하게, 여러 프로젝트에 걸쳐 구현해야 하는 사람"을 위한 것이다. 한 번 쓰고 말 프로젝트라면 공식 문서를 직접 붙여넣는 편이 더 최신일 수 있다.
이 스킬의 우선순위·예제·토큰 테이블 전부가 Compose를 1순위로 다룬다. Claude Code나 Codex로 UI를 자주 생성한다면, 매번 "MD3 스펙 좀 찾아줘"라고 시키는 대신 한 번 설치해 두고 /material-3 component …로 바로 정확한 코드를 받을 수 있다.
Flutter는 "2순위"로 성실하게 다뤄져 실무에 쓸 만하다. 다만 웹은 스킬 스스로 "유지보수 모드·Expressive 없음"이라고 계속 경고하므로, 최신 웹 인터랙션 트렌드를 원한다면 이 스킬만으론 부족하다.
여긴 실행할 게 없다. 이 레포를 이해하고 싶다면 코드를 실행하는 대신 SKILL.md와 references/*.md를 직접 읽고, "AI 에이전트에게 지식을 어떻게 구조화해 넣어주는가"라는 관점에서 바라봐야 한다. 오히려 이 관점 자체가 다른 도메인의 나만의 에이전트 스킬을 직접 만들 때 좋은 참고 템플릿이 된다 — 결정 트리, 안티패턴 목록, 감사 리포트 템플릿, 플랫폼 위계 선언이라는 네 요소를 그대로 빌려 쓸 수 있다.