Lucide-react 완벽 가이드: 설치부터 프로젝트 적용까지

이언덕·2025년 9월 25일
post-thumbnail

💡 공식문서

해당 글은 Lucide 공식문서를 참고해서 쉽게 이해할 수 있도록 정리해 놓은 글이다!
공식문서 글을 읽고 이 글을 읽으면 좋다

1. 🔍 Lucide-react란 무엇인가?

Lucide오픈소스 아이콘 라이브러리다.
1000개 이상의 벡터(SVG) 아이콘을 제공하며, 웹·앱 같은 디지털 프로젝트뿐 아니라 비디지털 영역에서도 활용할 수 있다.


이 프로젝트의 목표는 단순하다.
👉 디자이너와 개발자가 프로젝트에 아이콘을 쉽게 적용할 수 있도록, 다양한 공식 패키지를 제공하는 것이다.

📦 아이콘 종류와 확장성

Lucide는 여러 아이콘 변형(variants)과 상태(states)를 지원한다.
원하는 아이콘이 없다면 디자인 요청을 할 수 있고, 커뮤니티 기여자들이 새 아이콘을 추가해준다.
즉, 프로젝트가 커져도 필요한 아이콘을 계속 확장해 나갈 수 있는 구조다.

🎨 디자인 원칙

Lucide는 새로운 아이콘을 만들 때 몇 가지 규칙을 지킨다.

  • 알아보기 쉬움 (recognizability)
  • 일관된 스타일 (consistency)
  • 크기에 상관없는 가독성 (readability)

덕분에 아이콘이 단순히 예쁘기만 한 것이 아니라, 누가 봐도 직관적으로 이해할 수 있는 디자인을 유지한다.

⚡ 성능과 최적화

아이콘은 작은 자산 같지만, 쌓이면 프로젝트 성능에 영향을 줄 수 있다.
Lucide는 이를 고려해 다음을 제공한다.

  • SVG 압축으로 아이콘 용량 최소화
  • 트리 쉐이킹(tree-shaking) 지원 → 실제 사용하는 아이콘만 번들에 포함

결과적으로 웹 프로젝트의 배포 파일 크기를 줄이고 로딩 속도를 개선할 수 있다.

♿ 접근성(Accessibility)

아이콘은 “그림으로 의미를 전달하는 언어”다.
하지만 모든 사용자가 아이콘만 보고 의미를 이해하는 것은 아니다.
Lucide접근성 가이드를 함께 제공해, 더 많은 사람이 불편 없이 아이콘을 활용할 수 있도록 돕는다.

🌍 공식 패키지 지원

Lucide는 다양한 플랫폼을 지원한다.

  • Web (Vanilla JS)
  • React, React Native
  • Vue, Vue 3, Svelte, Preact, Solid
  • Angular, Astro, Node.js

그중에서 React 환경에서 바로 사용할 수 있도록 만든 패키지가 바로 lucide-react다.

👥 커뮤니티

Lucide활발한 커뮤니티 기반으로 운영된다.

  • GitHub에서 이슈·PR을 통해 의견을 나누고,
  • Discord에서 디자이너와 개발자들이 직접 소통한다.


2. 💡 왜 Lucide-react를 선택했는가?

🎯 아이콘 라이브러리의 필요성

프로젝트에서 아이콘은 단순한 장식이 아니라 정보를 직관적으로 전달하는 언어다.
버튼, 내비게이션, 상태 표시 등 다양한 UI 요소에서 아이콘은 사용자의 이해를 돕고, 디자인 완성도를 높인다.


하지만 직접 아이콘을 디자인하고 관리하는 것은 큰 비용이 든다.
그래서 개발자와 디자이너는 일관된 스타일을 가진 아이콘 세트를 활용하는 경우가 많다.

🪶 다른 아이콘 세트와 비교

Feather Icons

  • 미니멀한 디자인 언어로 큰 인기를 얻었으나, 현재는 유지보수가 중단된 상태
  • 300개 이상의 오픈 이슈와 100개 이상의 미처리된 PR이 쌓여 있음
  • 약 287개의 아이콘만 제공

Heroicons

  • Tailwind Labs에서 제작
  • Tailwind UI와 궁합이 좋고 UI 특화 아이콘이 풍부
  • 하지만 디자인 스타일이 비교적 고정적이라 다른 스타일의 프로젝트와는 어울리지 않을 수 있음

Material Icons

  • 구글 Material Design 기반
  • 수천 개 이상의 아이콘을 제공하지만 패키지가 크고 무겁다
  • 구글 디자인 언어에 종속적이라 자유도가 떨어짐

📈 Lucide의 장점

Lucide는 위 아이콘 세트의 단점을 보완하며, 다음과 같은 강점을 제공한다.

  • 가볍다: SVG 기반 + 트리쉐이킹 지원 → 필요한 아이콘만 번들에 포함
  • 일관성 있다: Feather의 미니멀한 스타일을 계승, 크기·두께·스타일이 통일감 있음
  • 커스터마이징 가능: 크기(size), 선 두께(strokeWidth), 색상(color) 등 props로 쉽게 변경
  • 풍부한 아이콘 수: Feather의 약 287개 대비 현재는 1000개 이상 제공
  • 활발한 커뮤니티: 디자인 요청 → 새 아이콘 추가 가능, 지속적인 업데이트 보장


3. ⚙️ 설치 및 기본 사용법

📦 설치 방법

Lucide-react는 패키지 매니저를 통해 간단히 설치할 수 있다.

# pnpm
pnpm add lucide-react
---
# npm
npm install lucide-react
---
# yarn
yarn add lucide-react

💻 기본 사용법

설치 후에는 원하는 아이콘을 import 해서 React 컴포넌트처럼 바로 사용할 수 있다.

import { Desktop, Calendar } from "lucide-react";
export default function App() {
  return (
    <div>
      <Desktop />
      <Calendar />
    </div>
  );
}

각 아이콘은 React 컴포넌트이기 때문에 JSX 안에서 바로 <Desktop /> 형태로 쓸 수 있다.

⚡ 트리쉐이킹(Tree-shaking) 지원

Lucide-react는 아이콘을 개별 import하기 때문에, 번들에는 실제 사용하는 아이콘만 포함된다.
→ 덕분에 불필요한 아이콘은 빌드에 포함되지 않아 성능과 용량을 최적화할 수 있다.



4. 🎨 아이콘 커스터마이징

Lucide-react의 강점 중 하나는 아이콘 속성을 쉽게 조정할 수 있다는 점이다. 모든 아이콘은 React 컴포넌트라서 props로 다양한 속성을 제어할 수 있다.

📏 크기 조정 (size)

size 속성으로 아이콘 크기를 변경할 수 있다. 기본값은 24이다.

<Desktop size={16} />   {/* 작은 아이콘 */}
<Desktop size={32} />   {/* 큰 아이콘 */}

✏️ 선 두께 조정 (strokeWidth)

strokeWidth 속성으로 선의 두께를 바꿀 수 있다. 기본값은 2이다.

<Desktop strokeWidth={1} />  {/* 얇은 선 */}
<Desktop strokeWidth={3} />  {/* 두꺼운 선 */}

🎨 색상 변경 (color)

color 속성으로 아이콘 색상을 지정할 수 있다. CSS 색상 값이라면 무엇이든 가능하다.

<Desktop color="red" />
<Desktop color="#06c" />   {/* 애플 블루 계열 */}

🎀 Tailwind와 함께 쓰기

Lucide 아이콘은 기본적으로 SVG라서 Tailwind 클래스를 그대로 적용할 수도 있다.

<Desktop className="w-6 h-6 text-blue-500" />
<Calendar className="w-8 h-8 text-gray-700" />

이 방식은 프로젝트 전체 스타일 시스템과 자연스럽게 통합할 때 유용하다.



5. 🛠️ 실제 프로젝트 적용 예시

lucide-react는 단순히 import { Home } from "lucide-react";처럼 불러와서 바로 사용할 수도 있다. 하지만 프로젝트가 커질수록 아이콘 사용이 여기저기 흩어지면 유지보수가 힘들고 스타일이 일관되지 않게 된다.

그래서 이번 프로젝트에서는 아이콘 시스템을 세 개의 파일로 나누어 관리했다.
1. Icon.tsx → 아이콘을 실제로 렌더링하는 공통 컴포넌트
2. Icon.registry.ts → 아이콘 목록을 한 곳에 모아둔 레지스트리
3. icon.ts → 아이콘 타입 정의

이 구조 덕분에 새로운 아이콘을 추가하거나 스타일을 변경할 때도 한 곳만 수정하면 전역에 반영할 수 있다.

1) Icon.tsx — 공통 아이콘 컴포넌트

import type { IconProps } from "@/types/icon";
import clsx from "clsx";
import { icons } from "./Icon.registry";
-
export function Icon({ name, size = 24, strokeWidth = 2, label, className, ...rest }: IconProps) {
  const Cmp = icons[name];
  return (
    <Cmp
      size={size}
      strokeWidth={strokeWidth}
      color="currentColor"
      className={clsx("text-gray-900", className)}
      aria-label={label}
      aria-hidden={label ? undefined : true}
      {...rest}
    />
  );
}

✅ 여기서 중요한 점

  • clsx 사용: className을 단순히 문자열로 합치지 않고 clsx를 사용 → 기본값(text-gray-900)과 외부에서 전달한 클래스(className)를 안전하게 병합.

  • 접근성 처리: label이 있으면 aria-label을 넣어서 스크린 리더가 읽을 수 있도록, 없으면 aria-hidden으로 시각적인 장식만 하도록 처리.

  • currentColor: 색상은 항상 currentColor로 고정 → Tailwindtext-* 클래스와 잘 연동되도록 설계.

즉, Icon.tsx는 아이콘을 단순히 보여주는 게 아니라 스타일·접근성·일관성까지 책임지는 wrapper다.



2) Icon.registry.ts — 아이콘 레지스트리

import {
  ArrowLeft,
  ArrowRight,
  Bell,
  BellRing,
  Calendar,
  CalendarDays,
  CalendarRange,
  Check,
  ...
  X,
} from "lucide-react";
/**
 * 아이콘 레지스트리
 * - 필요한 Lucide 아이콘만 import 후 객체로 매핑
 * - key는 프로젝트에서 사용할 이름 (camelCase)
 */
export const icons = {
  eye: Eye,
  eyeOff: EyeOff,
  check: Check,
  x: X,
  calendar: Calendar,
  calendarDays: CalendarDays,
  ...
} as const;
/** 아이콘 이름 타입 */
export type IconName = keyof typeof icons;
/** 아이콘 key 리스트 (예: map 렌더링에 활용) */
export const ICON_KEYS = Object.keys(icons) as IconName[];

✅ 여기서 중요한 점

  • 필요한 아이콘만 가져오기: lucide-react에는 1000개 이상의 아이콘이 있지만, 실제로 다 쓰지는 않는다. 프로젝트에서 쓸 아이콘만 import 해두면 번들 크기를 줄이고 관리도 쉬워진다.

  • camelCase 네이밍: calendarDays, arrowLeft처럼 key를 일관되게 camelCase로 관리 → 협업 시 혼란 줄이고, IDE 자동완성 기능 활용 가능.

  • 타입 안전성: IconName을 따로 정의해서 Icon.tsxname prop이 정확한 값만 받을 수 있도록 함. 잘못된 문자열을 입력하면 TypeScript가 에러로 잡아준다.

  • ICON_KEYS: Object.keys(icons)를 상수로 만들어두면, map 렌더링 시 유용하다. 예를 들어 "아이콘 선택 드롭다운" 같은 UI를 만들 때 자동으로 리스트를 돌릴 수 있다.

즉, 이 파일은 프로젝트 아이콘을 한눈에 보고, 한 곳에서 관리할 수 있게 해주는 중앙 관리소다.



3) icon.ts — 타입 정의

import type { IconName } from "@/shared/ui/Icon.registry";
import type { Calendar } from "lucide-react";
import type { ComponentProps } from "react";
/** Lucide 아이콘 공통 props */
type LucideBaseProps = ComponentProps<typeof Calendar>;
/**
 * 공통 Icon 컴포넌트 Props
 * - 색상은 Tailwind text-* 클래스로 제어
 * - color prop은 제외하고 항상 currentColor 사용
 */
export type IconProps = {
  name: IconName;
  /** 스크린리더용 라벨 (시각적 title 아님) */
  label?: string;
  /** 아이콘 크기 (기본 24) */
  size?: number;
  /** 선 굵기 (기본 2) */
  strokeWidth?: number;
  /** Tailwind 클래스와 결합 가능 */
  className?: string;
} & Omit<LucideBaseProps, "ref" | "color">;

✅ 여기서 중요한 점

  • LucideBaseProps 활용: ComponentProps<typeof Calendar>를 이용해 Lucide 아이콘의 기본 속성을 가져옴 → React 컴포넌트 props 타입을 그대로 활용.

  • color 제외: Lucide 기본 props에는 color가 있지만, 프로젝트에서는 항상 currentColor만 쓰도록 제한. 색상은 Tailwind text-* 클래스로만 제어하도록 통일.

  • 설명 달린 주석: 단순 타입 정의가 아니라 “왜 이렇게 했는지”를 주석으로 설명 → 협업할 때 이해가 빠르다.

이 파일은 Icon.tsx타입 안전하게 동작하도록 뒷받침해주는 역할을 한다.



4) 실제 사용 예시

import { Icon } from "@/shared/ui/Icon";
{/* === 아이콘 테스트 === */}
<h1 className="mb-6 text-2xl font-bold">📅 Icon Test</h1>
<div className="flex items-center gap-4">
  <Icon name="calendar" size={32} className="text-blue-600" />
  <span className="text-sm text-gray-700">Calendar 아이콘</span>
</div>

✅ 실행 결과 설명

  • <Icon name="calendar" />Icon.registry.ts에서 등록된 calendar 아이콘을 불러옴
  • size={32} → 크기를 32px로 키움
  • className="text-blue-600"Tailwind 클래스로 파란색 지정
  • <span>과 함께 배치해서 직관적인 UI 구성

즉, 실제 화면에서는 파란색 달력 아이콘 옆에 “Calendar 아이콘”이라는 텍스트가 나란히 표시된다.


👉 이런 구조를 만들어두면, 프로젝트 어디서든 <Icon name="something" />만 불러와서 손쉽게 아이콘을 적용할 수 있고, 아이콘이 바뀌거나 새로운 아이콘을 추가해도 레지스트리 하나만 수정하면 전역에 반영된다.



6. ⚖️ 장단점 정리

Lucide-react는 단순히 “아이콘 모음”이 아니라, React 환경에서 최적화된 아이콘 시스템이다. 그렇다면 실제 프로젝트에서 느낀 장점과 단점은 무엇일까?

✅ 장점

  1. 가벼움 (Lightweight)
    • 모든 아이콘이 svg 기반이라 기본적으로 용량이 작다.
    • tree-shaking을 지원해서 실제 사용하는 아이콘만 번들에 포함된다.
    • 덕분에 bundle size를 최소화할 수 있고, loading speed도 빨라진다.

  2. 일관성 (Consistency)
    • 원래 feather icons의 미니멀 디자인 철학을 계승했다.
    • strokeWidth, size, color 같은 속성을 동일하게 적용할 수 있어 프로젝트 전반의 스타일이 깔끔하게 유지된다.
    • 여러 개발자가 작업해도 아이콘 스타일이 들쭉날쭉해지지 않는다.

  3. 커스터마이징 (Customizable)
    • size, strokeWidth, className으로 자유롭게 조정 가능.
    • color 대신 currentColor를 쓰기 때문에, tailwind text-* 클래스와 바로 결합된다.
    • 다크 모드나 테마 변경에도 대응이 쉽다.

  4. 활발한 커뮤니티 (Active community)
    • feather icons가 방치된 것과 달리, Lucide는 활발하게 업데이트되고 있다.
    • GitHub issuesPR을 통해 새로운 아이콘 요청이 가능하며, 빠르게 반영된다.
    • Discord에서도 디자이너·개발자와 직접 소통할 수 있다.

  5. 멀티 플랫폼 지원 (Multi-platform support)
    • react, react-native, vue, svelte, angular, astro, node.js 등 다양한 환경에서 공식 패키지가 제공된다.
    • 한 번 배운 사용법을 여러 프레임워크에서 응용할 수 있다.

❌ 단점

  1. UI 특화 아이콘 부족
    • heroicons처럼 UI 컴포넌트에 바로 적용 가능한 특화 아이콘(예: 폼 필드, 모달 아이콘 등)은 상대적으로 적다.
    • Lucide는 범용적이고 미니멀한 스타일이라, 특정 UI 상황에서는 별도의 커스텀 아이콘이 필요하다.

  2. 아이콘 스타일 제약
    • 모든 아이콘이 outline 기반(선형 스타일)이라, filledduotone 스타일이 필요한 경우에는 한계가 있다.
    • 디자인 다양성보다는 통일성에 초점이 맞춰져 있다.

  3. 기존 프로젝트 마이그레이션 비용
    • feather icons에서 넘어올 때 일부 아이콘의 이름이 달라졌다.
    • 대규모 프로젝트라면 일괄 교체 작업이 필요할 수 있다.


      👉 정리하자면, lucide-react가볍고, 일관성 있고, 쉽게 커스터마이징 가능한 아이콘 라이브러리다. 다만 특정한 UI 상황에서는 부족한 부분이 있을 수 있으며, 다양한 스타일을 원하는 경우에는 다른 아이콘 세트와 병행해서 쓰는 것도 고려해야 한다.


7. ✅ 마무리 & 정리

lucide-react는 단순히 feather icons의 대체제가 아니다.
방치된 프로젝트를 대신해, 커뮤니티가 주도적으로 발전시켜온 확장성과 유지보수성을 모두 갖춘 아이콘 라이브러리다.

  • 간단한 설치: pnpm add lucide-react 한 줄로 바로 시작할 수 있다.
  • 손쉬운 사용법: import { Home } from "lucide-react"처럼 불러와 <Home />으로 바로 사용 가능하다.
  • 강력한 커스터마이징: size, strokeWidth, className으로 크기, 두께, 색상을 자유롭게 제어할 수 있다.
  • 중앙 집중식 관리: 이번 프로젝트에서처럼 Icon.tsx + Icon.registry.ts + icon.ts 구조를 잡으면 확장성까지 확보된다.


    👉 결론적으로, React 기반 프로젝트에서 가볍고 일관된 아이콘 세트를 찾고 있다면 lucide-react는 가장 추천할 만한 선택지다.

0개의 댓글