bootstrap-icons、feather-icons、font-awesome、heroicons、material-icons、octicons、react-icons はいずれもフロントエンド開発で広く使われるアイコンライブラリです。これらのパッケージは、Webアプリケーションに視覚的なアイコンを簡単に組み込むためのSVGやフォントベースのアセットを提供します。react-icons は複数のアイコンセットを1つのパッケージで提供するラッパーであるのに対し、他のパッケージはそれぞれ独自のデザイン言語(例:マテリアルデザイン、GitHubスタイル、Bootstrapテーマなど)に基づいています。開発者は、デザインの一貫性、バンドルサイズ、Reactとの統合性、カスタマイズのしやすさといった観点から適切なライブラリを選択する必要があります。
フロントエンド開発でアイコンを使うとき、どのパッケージを選ぶべきか迷うことはよくあります。見た目だけでなく、バンドルサイズ、使用方法、カスタマイズ性、フレームワークとの連携など、技術的な観点から慎重に選ぶ必要があります。この記事では、代表的な7つのアイコンライブラリを、実際のコード例を交えながら深く比較します。
まず、各パッケージが提供する基本的なインポートと使用方法を見てみましょう。
bootstrap-iconsSVGファイルを個別にインポートして使う方式です。CSSクラスによるフォントアイコンの使用も可能ですが、npm経由で使う場合はSVG推奨です。
// Bootstrap Icons
import { AlarmFill } from 'bootstrap-icons/icons';
function App() {
return <AlarmFill width="24" height="24" />;
}
feather-iconsすべてのアイコンが1つのオブジェクトに含まれており、関数として呼び出してSVG文字列を生成します。Reactで使うにはdangerouslySetInnerHTMLが必要です。
// Feather Icons
import * as feather from 'feather-icons';
function App() {
const iconHtml = feather.icons['activity'].toSvg();
return <span dangerouslySetInnerHTML={{ __html: iconHtml }} />;
}
font-awesome公式のReactコンポーネント(@fortawesome/react-fontawesome)とアイコンセット(例:@fortawesome/free-solid-svg-icons)を組み合わせて使います。
// Font Awesome
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCoffee } from '@fortawesome/free-solid-svg-icons';
function App() {
return <FontAwesomeIcon icon={faCoffee} />;
}
heroiconsReact向けに最適化されており、各アイコンはReactコンポーネントとして直接インポートできます。outlineとsolidの2種類があります。
// Heroicons
import { HomeIcon } from '@heroicons/react/24/outline';
function App() {
return <HomeIcon className="h-6 w-6 text-gray-500" />;
}
material-iconsGoogleのマテリアルデザインに準拠したアイコンで、通常はWebフォントとして使うのが一般的です。npmパッケージはCSSファイルとフォントファイルを含んでいます。
// Material Icons
import 'material-icons/iconfont/material-icons.css';
function App() {
return <i className="material-icons">home</i>;
}
octiconsGitHubが提供するアイコンセットで、Reactコンポーネントとして利用可能です。
// Octicons
import { HomeIcon } from '@primer/octicons-react';
function App() {
return <HomeIcon size={16} />;
}
react-icons複数のアイコンセット(Fa, Io, Mdなど)を1つのパッケージで提供。各アイコンはReactコンポーネントとして個別にインポートできます。
// React Icons
import { FaCoffee } from 'react-icons/fa';
function App() {
return <FaCoffee size="24px" color="brown" />;
}
アイコンの配信方法には大きく分けて2種類あります。
bootstrap-icons、heroicons、octicons、react-icons、font-awesome(React版)はSVGコンポーネントベースです。一方、material-iconsとfeather-icons(デフォルトのnpm使用法)はフォントまたはSVG文字列ベースであり、Reactでの使い勝手に注意が必要です。
特にfeather-iconsは、Reactで安全に使うには追加のラッパーが必要になるため、純粋なReactプロジェクトではやや面倒です。
アイコンの色やサイズをどう変更できるかも重要な判断材料です。
classNameやprops(size, colorなど)で自由にスタイル変更可能。colorやfont-sizeで調整可能だが、複雑なスタイル(パスごとの色分けなど)は不可。例として、色とサイズを動的に変える場合:
// Heroicons(簡単)
<HomeIcon className="text-blue-500 h-8 w-8" />
// Material Icons(CSS依存)
<i className="material-icons" style={{ color: 'blue', fontSize: '32px' }}>home</i>
// React Icons(propsで指定)
<FaHome color="blue" size="32" />
React専用プロジェクトであれば、Reactコンポーネントとして提供されているものが最も使いやすいです。
heroicons、octicons、react-icons、font-awesome(+ Reactコンポーネント)は、Reactのライフサイクルやpropsシステムに自然に統合されます。material-iconsやfeather-iconsは、React以外の環境(例:Vue、Svelte、プレーンHTML)でも使いやすいですが、Reactでは若干のラッピングが必要です。ツリーシェイキング(未使用コードの削除)に対応しているかどうかも重要です。
heroicons、react-icons、octicons、font-awesome(個別インポート時)は、個別のアイコンをインポートするため、未使用アイコンはバンドルに含まれません。material-iconsはフォント全体を読み込むため、使用アイコン数に関わらず一定のサイズになります。feather-iconsは全アイコンが1つのモジュールに含まれるため、1つだけ使っても全データがバンドルされる可能性があります(ただし、関数呼び出しで個別生成は可能)。import { BellIcon } from '@heroicons/react/24/outline';
function NotificationBell() {
return <BellIcon className="h-5 w-5 text-gray-700" />;
}
import { FaUser, IoMdSettings, MdHome } from 'react-icons/all';
import { MarkGithubIcon } from '@primer/octicons-react';
// 注意:dangerouslySetInnerHTMLが必要
const activityIcon = feather.icons.activity.toSvg({ width: 24, height: 24 });
import { HeartFill } from 'bootstrap-icons/icons';
material-icons npmパッケージ:公式ではWebフォントのCDN利用を推奨しており、npm経由での使用は非公式サポートです。バンドルサイズが大きくなるため、SPAでは避けた方が良い場合があります。feather-icons:Reactプロジェクトでは、SVG文字列を扱う必要があるため、XSS対策や型安全性の面で注意が必要です。代替として、react-featherなどのサードパーティ製コンポーネントを使う開発者も多いですが、これは今回の比較対象外です。| パッケージ | 形式 | React対応 | ツリーシェイキング | カスタマイズ性 | 推奨用途 |
|---|---|---|---|---|---|
bootstrap-icons | SVGコンポーネント | ◯(直接インポート) | ◯ | 高 | Bootstrapベースのプロジェクト |
feather-icons | SVG文字列 | △(dangerouslySetInnerHTML必要) | △ | 中 | シンプルな線アイコンが必要な場合 |
font-awesome | SVGコンポーネント(React版) | ◯(公式Reactコンポーネントあり) | ◯ | 高 | 豊富なアイコンセットが必要な場合 |
heroicons | SVGコンポーネント | ◯(最適化済み) | ◯ | 高 | Tailwind CSSユーザー |
material-icons | Webフォント | △(CSSクラス依存) | ✗ | 低 | マテリアルデザイン採用時 |
octicons | SVGコンポーネント | ◯(公式Reactコンポーネント) | ◯ | 高 | GitHub風UI |
react-icons | SVGコンポーネント | ◯(すべてReactコンポーネント) | ◯ | 高 | 複数アイコンセットを1つで管理したい場合 |
heroicons(Tailwind使用時)または react-icons(汎用性重視)が無難。octicons)を使う。アイコンは小さなUI要素ですが、選択によって開発体験やアプリのパフォーマンスに大きな影響を与えます。プロジェクトの要件に合ったものを冷静に選びましょう。
react-iconsは複数のアイコンセット(Font Awesome、Ionicons、Material Designなど)を1つのパッケージで統一的に扱いたい場合に非常に便利です。すべてのアイコンがReactコンポーネントとして提供され、ツリーシェイキングも効くため、必要な分だけバンドルできます。汎用性と柔軟性を重視するプロジェクトや、デザインシステムがまだ固まっていない初期段階の開発に適しています。
bootstrap-iconsはBootstrapフレームワークと併用しているプロジェクトや、そのデザイン体系に沿ったUIを構築したい場合に最適です。SVGコンポーネントとして個別にインポートでき、ツリーシェイキングにも対応しているため、バンドルサイズを効率的に抑えられます。ただし、Bootstrapを使っていないプロジェクトでは、デザインの整合性が取れない可能性があります。
material-iconsはGoogleのマテリアルデザインに厳密に従ったUIを構築する必要がある場合に適しています。ただし、npmパッケージはWebフォントを含むため、使用アイコン数に関わらず一定のバンドルサイズになります。また、Reactでの使用はCSSクラスに依存するため、動的なスタイル変更がやや制限されます。SPAではCDN利用を検討するのも一案です。
feather-iconsはミニマルで一貫性のある線アイコンが必要な場合に適しています。ただし、npm経由でReactプロジェクトで使う際にはSVG文字列をdangerouslySetInnerHTMLで挿入する必要があり、セキュリティや型安全性の面で注意が必要です。純粋なReactコンポーネントを求めるなら、代替ライブラリを検討した方が良いでしょう。
heroiconsはTailwind CSSユーザーにとって最適な選択肢です。Tailwind Labsが開発しており、クラス名との相性が非常に良く、Reactコンポーネントとして直接インポート可能です。outlineとsolidの2種類のスタイルがあり、UIの状態に応じて使い分けられます。バンドルサイズも小さく、ツリーシェイキングも効くため、新規Reactプロジェクトでの採用を強く推奨します。
octiconsはGitHubのUIと完全に一致させる必要がある場合(例:開発者向けツール、GitHub連携アプリ)に最適です。公式のReactコンポーネントが提供されており、サイズや色のカスタマイズも容易です。デザインの一貫性を重視するGitHubエコシステム内での利用を前提とした選択肢です。
font-awesomeは非常に豊富なアイコンセットと高いカスタマイズ性を求めるプロジェクトに適しています。公式のReactコンポーネント(@fortawesome/react-fontawesome)と組み合わせることで、SVGベースのアイコンを安全かつ柔軟に扱えます。ただし、依存パッケージが複数に分かれているため、初期設定がやや複雑になることがあります。
Include popular icons in your React projects easily with react-icons, which utilizes ES6 imports that allows you to include only the icons that your project is using.
yarn add react-icons
# or
npm install react-icons --save
example usage
import { FaBeer } from "react-icons/fa";
function Question() {
return (
<h3>
Lets go for a <FaBeer />?
</h3>
);
}
View the documentation for further usage examples and how to use icons from other packages. NOTE: each Icon package has it's own subfolder under react-icons you import from.
For example, to use an icon from Material Design, your import would be: import { ICON_NAME } from 'react-icons/md';
Note This option has not had a new release for some time. More info https://github.com/react-icons/react-icons/issues/593
If your project grows in size, this option is available. This method has the trade-off that it takes a long time to install the package.
yarn add @react-icons/all-files
# or
npm install @react-icons/all-files --save
example usage
import { FaBeer } from "@react-icons/all-files/fa/FaBeer";
function Question() {
return (
<h3>
Lets go for a <FaBeer />?
</h3>
);
}
You can add more icons by submitting pull requests or creating issues.
You can configure react-icons props using React Context API.
Requires React 16.3 or higher.
import { IconContext } from "react-icons";
<IconContext.Provider value={{ color: "blue", className: "global-class-name" }}>
<div>
<FaFolder />
</div>
</IconContext.Provider>;
| Key | Default | Notes |
|---|---|---|
color | undefined (inherit) | |
size | 1em | |
className | undefined | |
style | undefined | Can overwrite size and color |
attr | undefined | Overwritten by other attributes |
title | undefined | Icon description for accessibility |
Import path has changed. You need to rewrite from the old style.
// OLD IMPORT STYLE
import FaBeer from "react-icons/lib/fa/beer";
function Question() {
return (
<h3>
Lets go for a <FaBeer />?
</h3>
);
}
// NEW IMPORT STYLE
import { FaBeer } from "react-icons/fa";
function Question() {
return (
<h3>
Lets go for a <FaBeer />?
</h3>
);
}
Ending up with a large JS bundle? Check out this issue.
From version 3, vertical-align: middle is not automatically given. Please use IconContext to specify className or specify an inline style.
<IconContext.Provider value={{ style: { verticalAlign: 'middle' } }}>
className StylingComponent
<IconContext.Provider value={{ className: 'react-icons' }}>
CSS
.react-icons {
vertical-align: middle;
}
Dependencies on @types/react-icons can be deleted.
yarn remove @types/react-icons
npm remove @types/react-icons
./build-script.sh will build the whole project. See also CI scripts for more information.
yarn
cd packages/react-icons
yarn fetch # fetch icon sources
yarn build
First, check the discussion to see if anyone would like to add an icon set.
https://github.com/react-icons/react-icons/discussions/categories/new-icon-set
The SVG files to be fetched are managed in this file. Edit this file and run yarn fetch && yarn check && yarn build.
https://github.com/react-icons/react-icons/blob/master/packages/react-icons/src/icons/index.ts
Note The project is not actively accepting PR for the preview site at this time.
The preview site is the react-icons website, built in Astro+React.
cd packages/react-icons
yarn fetch
yarn build
cd ../preview-astro
yarn start
The demo is a Create React App boilerplate with react-icons added as a dependency for easy testing.
cd packages/react-icons
yarn fetch
yarn build
cd ../demo
yarn start
SVG is supported by all major browsers. With react-icons, you can serve only the needed icons instead of one big font file to the users, helping you to recognize which icons are used in your project.
MIT