본문으로 건너뛰기Skip to content
lucianLabs Icons

API · v2.0.13

아이콘을 앱의 실제 상태에 연결하기Wire icons to your app’s real state

아이콘 211개는 모두 같은 커스텀 요소 API를 씁니다. 스크립트 한 줄로 불러오고, 속성으로 꾸미고, 앱의 상태가 바뀔 때 setState()를 부르면 됩니다. 의존성은 없고 MIT 라이선스예요.

All 211 icons share one custom element API. Load them with one script, style them with attributes, and call setState() when your app’s state changes. No dependencies, MIT licensed.

01설치Install

빠르게 써 보려면 전체 묶음을 불러오세요. 211개가 모두 <lucian-이름> 요소로 등록됩니다.

To try things quickly, load the full bundle. All 211 icons register as <lucian-name> elements.

<script type="module" src="https://lucianlabs.dev/icons/all.js"></script>

필요한 아이콘만 쓰려면 개별 모듈을 불러옵니다. 모듈은 같은 폴더의 runtime.js를 함께 가져옵니다.

To ship only what you use, load individual modules. Each one imports the shared runtime.js next to it.

<script type="module" src="https://lucianlabs.dev/icons/modules/heart.js"></script>
<script type="module" src="https://lucianlabs.dev/icons/modules/download.js"></script>

공개 주소는 항상 최신 버전을 가리킵니다. 실제 서비스에서는 modules/아이콘.js와 modules/runtime.js를 프로젝트에 복사해 버전을 고정하세요. 에이전트 스킬의 get --out 명령으로 받을 수 있어요.

Public URLs always point at the latest release. In production, copy modules/icon.js and modules/runtime.js into your project to pin the version. Get them with the agent skill’s get --out command.

02기본 사용Basics

기존 버튼이나 링크 안에 넣으세요. 아이콘은 가장 가까운 button, a, [role=button] 같은 컨트롤에 마우스를 올리거나 키보드로 포커스하면 효과를 재생합니다. 터치에서는 누를 때 재생해요.

Put the icon inside your existing button or link. It plays its effect when the nearest control (button, a, [role=button] and similar) is hovered or receives keyboard focus, and on press for touch.

<button type="button" class="like" aria-pressed="false">
  <lucian-heart></lucian-heart>
  <span>좋아요</span>
</button>
링크Link

아이콘은 기본적으로 장식으로 취급되어 보조 기술에서 숨겨집니다. 버튼의 글자나 aria-label을 그대로 두세요. 글자 없이 아이콘만으로 뜻을 전한다면 label 속성에 현지화된 설명을 넣습니다.

Icons are decorative by default and hidden from assistive technology. Keep your button’s text or aria-label. When the icon alone carries meaning, give it a localized label.

03속성Attributes

속성Attribute값Values설명What it does
state아이콘별 상태Per icon현재 상태. 바뀌면 이전 상태에서 스프링으로 전환됩니다. 지원하지 않는 값은 기본 상태로 돌아가요.Current state. Changing it springs from the previous state. Unsupported values fall back to the default.
size8–512 · 24CSS 픽셀 크기. CSS 변수 --li-size로도 정할 수 있어요.Size in CSS pixels. The --li-size variable works too.
tonecolor · linecolor는 아이콘 고유 색으로 면과 포인트를 칠하고, line은 모든 선을 글자색 한 가지로 그립니다. line에 accent를 더하면 포인트만 그 색이 됩니다.color paints surfaces and details in the icon’s own hue; line draws everything in the text color. Add accent to line to color only the details.
accentCSS 색CSS color고유 색 대신 쓸 색. #hex, rgb(), oklch(), 색 이름을 받습니다. 다운로드, 업로드, 방패의 실패 표시는 항상 빨간색입니다.Replaces the icon’s own hue. Accepts #hex, rgb(), oklch() and named colors. Error marks on download, upload and shield stay red.
weight0.5–3 · 1.75선 굵기(24 그리드 기준).Stroke width on the 24 grid.
progress0–100다운로드, 업로드, 배터리만. 실제로 잰 진행률을 넣으세요.Download, upload and battery only. Pass measured progress.
label문자열Text있으면 role="img"와 이름이 붙고, 없으면 장식으로 숨겨집니다.Adds role="img" and a name. Without it the icon stays decorative.
animatehover · click · none효과를 재생할 때. none이면 상태 전환만 움직입니다.When the effect plays. With none, only state changes move.

04메서드Methods

setState(name)상태를 바꿉니다. 지원하지 않는 이름이면 RangeError를 던져요.Changes state. Throws RangeError for unsupported names.
setProgress(n)0–100으로 잘라 진행률을 옮깁니다. 진행률이 없는 아이콘은 TypeError.Moves progress, clamped to 0–100. Throws TypeError on icons without progress.
play()효과를 한 번 재생합니다. 재생 중이거나 동작 줄이기 설정이면 false.Plays the effect once. Returns false while one is running or under reduced motion.
next()다음 상태로 넘기고 그 이름을 돌려줍니다. 상태가 없는 아이콘은 효과를 재생하고 null.Advances to the next state and returns it. Icons without states play their effect and return null.
.state · .states현재 상태와 지원 상태 목록(읽기 전용).Current state and the supported list (read only).
.definition아이콘 정의 데이터(이름, 색, 키워드, 상태 이름).The icon’s definition data (names, color, keywords, state labels).

요소는 문서 전역 이벤트나 타이머를 등록하지 않습니다. 가장 가까운 컨트롤에 붙인 리스너는 요소가 문서에서 빠지면 함께 정리돼요.

The element registers no document listeners or timers. Listeners on the nearest control are removed when the element leaves the document.

05상태는 앱이 정합니다Your app owns the state

상태가 있는 아이콘 52개는 앱의 실제 상태를 보여 주는 표시등입니다. 클릭은 성공이 아니에요. 요청이 끝났을 때, 값이 실제로 바뀌었을 때 setState()를 부르세요.

The 52 stateful icons are indicators of real application state. A click is not success. Call setState() when the request settles or the value actually changes.

const button = document.querySelector('#export');
const icon = button.querySelector('lucian-download');

button.addEventListener('click', async () => {
  icon.setState('progress');
  try {
    await exportReport({ onProgress: percent => icon.setProgress(percent) });
    icon.setState('success');
  } catch (error) {
    icon.setState(error.name === 'AbortError' ? 'idle' : 'error');
  }
});

시연용 컨트롤Demo controls · idle

진행률을 모르면 숫자를 지어내지 말고 progress 상태만 두세요. 진행률 100은 성공과 다릅니다. 버튼의 disabled, aria-busy, aria-pressed, 상태 문구는 요소가 건드리지 않으니 앱에서 관리합니다.

If you don’t know the progress, don’t invent a number; stay in progress. Progress 100 is not success. The element never touches your button’s disabled, aria-busy, aria-pressed or status text; your app manages them.

Promise 연동 예제는 자동 성공 타이머 없이 대기, 성공, 실패, 취소를 직접 눌러 확인합니다.

The Promise integration example lets you resolve, reject and cancel by hand, with no timer faking success.

06색과 톤Color and tone

선은 언제나 글자색(currentColor)을 따르고, 면과 포인트는 아이콘마다 고른 고유 색을 씁니다. 페이지가 color-scheme: dark를 선언한 다크 테마에서는 면이 어두운 배경에 묻혀 탁해지지 않도록 아이콘 색을 조금 더 깊고 진하게 칠하고, 포인트는 조금 밝게 바꿔요. 하트나 별처럼 상태에 따라 채워지는 아이콘은 꺼짐일 때 테두리만 남아요. 다크 테마라면 대개 이미 선언되어 있어요.

Strokes always follow the text color (currentColor); surfaces and details use each icon’s own hue. When the page declares color-scheme: dark, surfaces are painted in a slightly deeper, richer version of the icon’s color so they do not turn muddy on a dark background, and details get a little lighter. Icons that fill with their state, such as heart and star, are just an outline when off. Most dark themes already declare it.

color
tone="line"
accent
weight="2.5"
/* 브랜드 색 하나로 맞추기 · One brand hue */
.toolbar { --li-accent: var(--brand); }

/* 면 채움 진하기 0–1 (기본 .24) · Surface tint 0–1 (default .24) */
.dense { --li-tint: 0; }

/* 크기와 굵기 · Size and weight */
.nav lucian-home { --li-size: 20px; --li-weight: 2; color: var(--text-2); }

07모션과 접근성Motion and accessibility

  • 스프링 전환. 상태가 바뀌면 부품마다 스프링 곡선으로 움직입니다. 전환 중에 다시 바뀌어도 지금 그려진 자리에서 이어서 갑니다.
  • 겹쳐지는 효과. 마우스 효과는 상태 위에 더해지는 방식이라 열린 상태의 쓰레기통도 자연스럽게 흔들립니다.
  • 상태 루프. 전화의 ringing, 새로고침의 loading처럼 계속 움직여야 하는 상태는 그 상태일 때만 반복하고, 벗어나면 한 바퀴를 마저 돈 뒤 멈춥니다.
  • 동작 줄이기. prefers-reduced-motion이 켜져 있으면 움직임 없이 최종 모양과 진행률만 바로 보여 줍니다.
  • 격리. 아이콘마다 자기 Shadow DOM을 써서 SVG ID나 CSS가 서로 부딪치지 않습니다. 같은 아이콘을 여러 개 써도 괜찮아요.
  • Spring transitions. Each part springs to its new pose. If the state changes mid-flight, motion continues from where it is drawn.
  • Additive effects. Hover effects add on top of the state, so an open trash can still wiggles naturally.
  • State loops. States that keep moving, like the phone’s ringing or refresh’s loading, loop only while active and finish their cycle on exit.
  • Reduced motion. With prefers-reduced-motion, icons jump straight to the final pose and progress.
  • Isolation. Every icon has its own shadow root, so SVG IDs and CSS never collide. Repeat icons freely.

08프레임워크Frameworks

React

클라이언트에서 모듈을 불러오고 속성으로 상태를 넘기세요. React 19는 커스텀 요소의 속성을 그대로 전달합니다.

Import the module on the client and pass state as an attribute. React 19 forwards custom element attributes as is.

import './vendor/lucian-icons/heart.js';

export function LikeButton({ liked, onToggle }) {
  return (
    <button type="button" aria-pressed={liked} onClick={onToggle}>
      <lucian-heart state={liked ? 'on' : 'off'} />
      <span>Like</span>
    </button>
  );
}

Next.js 같은 SSR 환경에서는 'use client' 컴포넌트나 useEffect 안에서만 불러오세요. TypeScript에서는 JSX.IntrinsicElements에 'lucian-heart'를 선언합니다.

In SSR frameworks like Next.js, import only in a 'use client' component or inside useEffect. In TypeScript, declare 'lucian-heart' in JSX.IntrinsicElements.

Vue · Svelte

// vite.config.js
vue({ template: { compilerOptions: { isCustomElement: tag => tag.startsWith('lucian-') } } })

<!-- Svelte -->
<lucian-bell state={unread ? 'unread' : 'idle'}></lucian-bell>

09내려받기 형식Formats

JS 모듈modulemodules/<id>.js + runtime.js움직임과 상태가 모두 들어 있는 본편.The full icon, with motion and state.
SVGdownloads/svg/<id>.svg선택한 상태와 색으로 멈춘 정지 이미지. 디자인 도구용.A still image in the chosen state and color, for design tools.
HTMLdownloads/html/<id>.html런타임까지 담은 단일 파일 시연. 파일로 바로 열어도 동작합니다.A single-file demo with the runtime inlined. Opens straight from disk.
프롬프트Prompt상세 창Detail view아이콘 코드와 적용 지침. AI 코딩 도구에 붙여넣습니다.Icon code plus integration rules, for AI coding tools.
JSONapi/v1/catalog.json이름, 키워드, 색, 상태, 해시를 담은 카탈로그. 아이콘별 정의는 api/v1/icons/<id>.json.Catalog with names, keywords, colors, states and hashes. Per icon: api/v1/icons/<id>.json.

10에이전트 스킬Agent skill

스킬을 설치하면 Claude Code와 Codex가 카탈로그에서 알맞은 아이콘을 찾아 기존 버튼과 상태에 연결합니다. 오프라인으로 동작하고, 고른 아이콘의 코드만 읽어요. 갤러리 번호로도 부를 수 있어요. “lucian-icons로 197번 아이콘 넣어줘”처럼 말하면 하트가 들어가요.

With the skill installed, Claude Code and Codex search the catalog, pick the right icon and wire it to your existing buttons and state. It works offline and reads only the code it picks. You can also ask by gallery number: “Use lucian-icons to add icon 197” adds the heart.

스킬 받기 (ZIP)Download skill (ZIP)

도구Tool프로젝트Project사용자 전체User부르기Invoke
Claude Code.claude/skills/lucian-icons/~/.claude/skills/lucian-icons//lucian-icons
Codex.agents/skills/lucian-icons/~/.agents/skills/lucian-icons/$lucian-icons

압축을 풀면 나오는 lucian-icons 폴더 바로 안에 SKILL.md가 있어야 합니다. 새 스킬이 보이지 않으면 에이전트를 다시 시작하세요. CLI는 Node.js 18 이상에서 패키지 설치 없이 돌아갑니다.

The unzipped lucian-icons folder must contain SKILL.md directly. Restart the agent if a new skill doesn’t show up. The CLI runs on Node.js 18+ with nothing to install.

node <skill-dir>/scripts/lucian-icons.mjs search 다운로드
node <skill-dir>/scripts/lucian-icons.mjs get download heart
node <skill-dir>/scripts/lucian-icons.mjs get download heart --out ./src/vendor/lucian-icons

--out은 고른 모듈과 runtime.js, LICENSE만 복사하고 이미 있는 파일은 덮어쓰지 않습니다.

--out copies only the chosen modules, runtime.js and LICENSE, and never overwrites existing files.

11상태 목록State list

상태가 있는 아이콘과 상태 이름입니다. 첫 번째가 기본 상태예요. 나머지 아이콘은 상태 없이 효과만 재생합니다.

Icons with states and their state names. The first one is the default. All other icons only play an effect.

아이콘Icon상태States
trash 쓰레기통Trashclosedopen
folder 폴더Folderclosedopen
download 다운로드Downloadidleprogresssuccesserror
upload 업로드Uploadidleprogresssuccesserror
clipboard 클립보드Clipboardidledone
archive 보관함Archiveclosedopen
inbox 받은편지함Inboxemptyreceived
copy 복사Copyidlecopied
link 링크Linklinkedbroken
bookmark 북마크Bookmarkoffon
cloud 클라우드Cloudidlesyncingsynced
save 저장Saveidlesaved
envelope 봉투Envelopeclosedopen
bell 알림Bellidleunread
chat 대화Chatidletyping
phone 전화Phoneidleringing
videochat 영상 통화Video callonoff
thumbsup 좋아요Thumbs upoffon
lock 자물쇠Locklockedunlocked
shield 방패Shieldprotectedalert
fingerprint 지문Fingerprintidlescanning
siren 경광등Sirenoffon
search 검색Searchidlesearching
menu 메뉴Menuclosedopen
filter 필터Filteroffon
sort 정렬Sortdescasc
layout 레이아웃Layoutopencollapsed
refresh 새로고침Refreshidleloading
chevron 펼침 화살표Chevroncollapsedexpanded
star 별Staroffon
toggle 스위치Toggleoffon
play 재생Playpausedplaying
record 녹화Recordidlerecording
music 음악Musicidleplaying
microphone 마이크Microphoneonmuted
speaker 스피커Speakeronmuted
tv TVTVonoff
disc 음반Discidleplaying
power 전원Poweroffon
tablet 태블릿Tabletportraitlandscape
smartphone 스마트폰Smartphoneidlealert
battery 배터리Batterylevelcharging
wifi 와이파이Wi-Ficonnectedconnecting
bulb 전구Light bulboffon
signal 신호Signalfullsearching
cast 화면 전송Castidlecasting
cart 장바구니Cartemptyadded
gift 선물Giftclosedopen
umbrella 우산Umbrellaopenclosed
heart 하트Heartoffon
stopwatch 스톱워치Stopwatchidlerunning
lamp 스탠드Lampoffon

121.x에서 옮기기Moving from 1.x

  • 색. ink, paper 속성은 없어졌습니다. 선은 color(글자색)를, 포인트는 accent나 --li-accent를 쓰세요.
  • 상태. 상태는 실제 앱 상태를 나타낼 때만 남겼습니다. 예를 들어 벨은 ringing 대신 unread가 되었고, 마우스 반응만 있던 아이콘 69개는 상태 없이 효과로 바뀌었어요. 상태 이름은 위 목록을 확인하세요.
  • 효과. 마우스와 포커스 반응이 자동으로 붙습니다. 직접 제어하려면 animate="none"과 play()를 쓰세요.
  • 이전 버전. 1.x 패키지는 스킬 1.2.0으로 계속 받을 수 있습니다.
  • Color. The ink and paper attributes are gone. Strokes use color (the text color); details use accent or --li-accent.
  • States. States remain only where they mirror real app state. The bell’s ringing became unread, for example, and 69 hover-only icons now play an effect without states. Check the list above for names.
  • Effects. Hover and focus responses attach automatically. For manual control use animate="none" and play().
  • Older versions. 1.x packages remain available: skill 1.2.0.

13라이선스License

라이브러리 코드와 카탈로그 아이콘은 MIT © 2026 Lucian입니다. 상업적으로 쓰고 고쳐도 되며, 배포할 때 저작권 고지만 남겨 주세요. 아이콘은 모두 직접 그린 오리지널이고, 사이트 글꼴 Pretendard와 Geist Mono는 SIL Open Font License를 따릅니다(외부 자산 고지). Lucian·lucianLabs 이름과 로고는 브랜드 자산으로, 아이콘의 MIT 배포 범위에 포함되지 않으며 상표 사용권을 부여하지 않습니다(브랜드 안내).

Library code and catalog icons are MIT © 2026 Lucian. Use and modify them commercially; keep the copyright notice when you redistribute. Every icon is an original drawing. The site fonts Pretendard and Geist Mono are under the SIL Open Font License (notices). The Lucian and lucianLabs names and logos are reserved brand assets, excluded from the icon library’s MIT grant; no trademark rights are granted (brand notice).