はじめに
自作のアイコンはもちろん、Material DesignやFont Awesomeのアイコンをsvgファイルとしてコピーしたり、React IconやMaterial UIのMaterial Iconのようなライブラリを通してコンポーネントとして利用するなど、ReactでIconを利用する方法はさまざまです。
この記事ではそんなReactでIconを利用する方法の1つである、Lucideを紹介します。
Lucide
Lucideはアイコンやシンボルを表示するためにsvgを提供するOSSライブラリです。この記事ではReactにおける活用を紹介しますが、Vanilla JSはもちろん、Vue、Svelte、Solid、React Native、Angular、Preactなどさまざまなケースに対応しています。
アイコンは多様で、執筆現在で1917個ものアイコンが用意されています。骸骨のアイコンもあるくらいなので、ほとんどのケースで欲しいアイコンがここから見つかると思います(最近はここから使えそうなアイコンを物色するくらいです)。

Webページからアイコンの一覧を見ることができます。svgのcolor、storoke-width、sizeを一度に調整する機能やアイコンの検索機能が備わっており不自由なくアイコンの海を泳げます。
Reactアプリケーションに導入する
実際にReactのアプリケーションにLucideを取り入れる方法を紹介します。
pnpm i lucide-react
ライブラリのインストールが終了したら準備完了です。通常のIconであればlucide-reactからインポートしてそのまま使えます。
import { Squirrel } from 'lucide-react';
export const Sample = () => {
return <Squirrel color="#50e2d2" size={48} />;
};
インポートしたコンポーネントには通常のsvgに渡せるpropsのほかに、追加してsize、color、strokeWidth、absoluteStrokeWidthを渡せます。
sizeはアイコンの大きさで、デフォルトは24です。渡した数値pxで表示されます。
// 48pxのリスのアイコン
<Squirrel color="#50e2d2" size={48} />
colorはstrokeの色を指定します。デフォルトはcurrentColorです。svgのcolor属性には追加されないので注意しましょう。
// 輪郭が#50e2d2のリスのアイコン
<Squirrel color="#50e2d2" size={48} />
strokeWidthは輪郭の大きさです。デフォルトは2です。
// 輪郭が3のリスのアイコン
<Squirrel color="#50e2d2" size={48} strokeWidth={3} />
absoluteStrokeWidthはstrokeWidthを元にstroke-width属性を決めます。
デフォルトはfalseで、strokeWidthのままstroke-width属性に値を渡します。
trueにしたときはstrokeWidthに24掛けたものをsizeで割った値になります。
lucide-lab
Lucideには調査中のアイコンがあります。
pnpm i @lucide/lab
追加のインストールを行い、IconコンポーネントのiconNodeに@lucide/labから取ってきたアイコンを渡します。
import { Icon } from "lucide-react";
import { avocado } from "@lucide/lab";
export const Sample = () => {
return (
<>
<Icon iconNode={avocado} color="#50e2d2" size={48} />
</>
);
};
塗りつぶす
アイコンの塗りつぶしは完全にサポートされていません。fill属性を付与してアイコンを塗りつぶした状態にします。
import { Squirrel } from "lucide-react";
export const Sample = () => {
return <Squirrel fill="#50e2d2" color="#50e2d2" size={48} />;
};
アクセシビリティ
アイコンがテキストの補足のためであればそのままで良いですが、アイコンが単体で意味を持っている場合はアクセシブルな名前を付与する必要があります。名前はaria-labelを通して付与します。
import { Squirrel } from "lucide-react";
export const Sample = () => {
return (
<button>
<Squirrel aria-label="リス" color="#50e2d2" size={48} />
</button>
);
};
一般的にaria-labelでラベルを付与することは、完璧な対応とは言えません。tailwindcssのsr-onlyのような実装が可能であればそちらを利用するようにしてください。
他の名前
これまでlucide-reactからアイコンを意味する単語をそのままの名前でインポートしてきました。そのままの名前の場合既存のコンポーネントと名前が衝突してどちらかの名前を変更する必要が出てきます(EditとかHomeとか)。lucide-reactではそのままの名前の他に、suffixにIconがついたものとprefixにLucideがついた同一のアイコンが提供されています。
import { Squirrel, SquirrelIcon, LucideSquirrel } from "lucide-react";
export const Sample = () => {
return (
<>
<Squirrel color="#50e2d2" size={48} />
<SquirrelIcon color="#50e2d2" size={48} />
<LucideSquirrel color="#50e2d2" size={48} />
</>
);
};
利用する名前を1種類にする制約を課したい場合はlucide.d.tsのようなものを作ってtsconfig.tsに渡します。
// prefixだけ
declare module "lucide-react" {
export * from "lucide-react/dist/lucide-react.prefixed";
}
// suffixだけ
declare module "lucide-react" {
export * from "lucide-react/dist/lucide-react.suffixed";
}
そのままの名前だけにする方法は今のところないようです。
おわりに
私はLucideのアイコンが豊富で捜索しやすい点を特に気に入っています。ライブラリとして利用する時も不便を感じることなく利用できるので、デザイン上でアイコンの見た目の制約がない場合は利用してみてはいかがでしょうか。とてもおすすめです。