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>아이콘은 기본적으로 장식으로 취급되어 보조 기술에서 숨겨집니다. 버튼의 글자나 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. |
size | 8–512 · 24 | CSS 픽셀 크기. CSS 변수 --li-size로도 정할 수 있어요.Size in CSS pixels. The --li-size variable works too. |
tone | color · line | color는 아이콘 고유 색으로 면과 포인트를 칠하고, 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. |
accent | CSS 색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. |
weight | 0.5–3 · 1.75 | 선 굵기(24 그리드 기준).Stroke width on the 24 grid. |
progress | 0–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. |
animate | hover · 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.
/* 브랜드 색 하나로 맞추기 · 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
ringingor refresh’sloading, 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 모듈module | modules/<id>.js + runtime.js | 움직임과 상태가 모두 들어 있는 본편.The full icon, with motion and state. |
| SVG | downloads/svg/<id>.svg | 선택한 상태와 색으로 멈춘 정지 이미지. 디자인 도구용.A still image in the chosen state and color, for design tools. |
| HTML | downloads/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. |
| JSON | api/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.
| 도구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 |
|---|---|
closedopen | |
closedopen | |
idleprogresssuccesserror | |
idleprogresssuccesserror | |
idledone | |
closedopen | |
emptyreceived | |
idlecopied | |
linkedbroken | |
offon | |
idlesyncingsynced | |
idlesaved | |
closedopen | |
idleunread | |
idletyping | |
idleringing | |
onoff | |
offon | |
lockedunlocked | |
protectedalert | |
idlescanning | |
offon | |
idlesearching | |
closedopen | |
offon | |
descasc | |
opencollapsed | |
idleloading | |
collapsedexpanded | |
offon | |
offon | |
pausedplaying | |
idlerecording | |
idleplaying | |
onmuted | |
onmuted | |
onoff | |
idleplaying | |
offon | |
portraitlandscape | |
idlealert | |
levelcharging | |
connectedconnecting | |
offon | |
fullsearching | |
idlecasting | |
emptyadded | |
closedopen | |
openclosed | |
offon | |
idlerunning | |
offon |
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
inkandpaperattributes are gone. Strokes usecolor(the text color); details useaccentor--li-accent. - States. States remain only where they mirror real app state. The bell’s
ringingbecameunread, 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"andplay(). - 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).