react-feather、react-fontawesome、react-icons、react-svgは、Reactアプリケーションでアイコンを扱うための代表的なnpmパッケージです。これらはそれぞれ異なるアプローチでアイコンの提供やレンダリングを実現しており、バンドルサイズ、柔軟性、開発体験に大きな影響を与えます。react-featherはFeather Icons専用の軽量コンポーネント群を提供し、react-fontawesomeはFont Awesomeの公式React統合を実現しています。react-iconsは複数のアイコンセットを1つのパッケージで横断的に利用できるメタライブラリであり、react-svgは外部SVGファイルをReactコンポーネントとして動的に読み込むためのユーティリティです。
Reactアプリでアイコンを使うとき、どのパッケージを選ぶべきか迷うことはよくあります。それぞれのアプローチは大きく異なり、バンドルサイズ、柔軟性、メンテナンス性に直接影響します。この記事では、4つの主要な選択肢を実際のコードとともに深く比較し、プロジェクトの要件に応じた最適な判断をサポートします。
まず、各パッケージが何を解決しようとしているかを理解しましょう。
react-feather は、Feather Iconsという軽量で一貫性のあるアイコンセットをReactコンポーネントとして提供します。すべてのアイコンが個別のReactコンポーネントとしてエクスポートされており、Tree Shakingによって未使用のアイコンはバンドルに含まれません。
react-fontawesome は、Font Awesomeの公式Reactラッパーです。Font Awesomeは非常に広範なアイコンライブラリであり、Free版とPro版の両方に対応しています。このパッケージは、アイコンをフォントとして扱う従来の方法ではなく、SVGベースのコンポーネントとして提供することで、スタイルやアクセシビリティを改善しています。
react-icons は、複数の人気アイコンセット(Feather、FontAwesome、Material Design Icons、Lucideなど)を1つのパッケージで統合的に利用できるメタライブラリです。必要なアイコンだけをインポートでき、Tree Shakingにも対応しています。
react-svg は、外部SVGファイルをReactコンポーネントとして動的に読み込むためのユーティリティです。アイコンそのものを提供するのではなく、「任意のSVGをReactで扱う仕組み」を提供します。これは、カスタムSVGアセットやデザインシステム固有のアイコンを利用する場合に便利です。
react-feather各アイコンは個別のコンポーネントとして提供されます。必要なものだけをインポートすれば、バンドルサイズを最小限に抑えられます。
import { Camera, Heart } from 'react-feather';
function App() {
return (
<div>
<Camera size={24} color="blue" />
<Heart fill="red" stroke="none" />
</div>
);
}
react-fontawesomeまず、使用するアイコンをライブラリに追加する必要があります(Tree Shakingのため)。その後、FontAwesomeIconコンポーネントでレンダリングします。
import { library } from '@fortawesome/fontawesome-svg-core';
import { faCoffee, faUser } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
library.add(faCoffee, faUser);
function App() {
return (
<div>
<FontAwesomeIcon icon="coffee" size="2x" color="brown" />
<FontAwesomeIcon icon="user" style={{ color: 'gray' }} />
</div>
);
}
react-iconsアイコンセットごとにサブディレクトリがあり、そこから直接インポートします。Tree Shakingが効くため、使わないアイコンはバンドルされません。
import { FaCoffee } from 'react-icons/fa';
import { FiCamera } from 'react-icons/fi';
function App() {
return (
<div>
<FaCoffee size={32} color="saddlebrown" />
<FiCamera size="1.5em" />
</div>
);
}
react-svgSVGファイルのパスを指定して、非同期で読み込みます。ローディング状態やエラー処理も考慮する必要があります。
import ReactSVG from 'react-svg';
function App() {
return (
<div>
<ReactSVG
src="/icons/camera.svg"
wrapper="span"
className="icon"
afterInjection={(error, svg) => {
if (error) console.error(error);
}}
/>
</div>
);
}
react-feather と react-icons は、ES Modulesによる個別インポートを前提として設計されており、WebpackやViteなどのモダンなバンドラと組み合わせると、未使用のアイコンは完全にバンドルから除外されます。特に小規模なアプリや、少数のアイコンしか使わないケースでは非常に効率的です。
react-fontawesome も同様にTree Shakingに対応していますが、アイコンをlibrary.add()で明示的に登録する手順が必要です。この手順を忘れると、全アイコンがバンドルに含まれる可能性があります(ただし、最近のバージョンでは直接インポート方式も推奨されています)。
react-svg は、SVGファイルを外部リソースとして扱うため、初期バンドルサイズにはほとんど影響しません。しかし、ランタイムでネットワークリクエストが発生するため、レイアウトシフトやローディング遅延のリスクがあります。また、キャッシュ戦略を自分で考える必要があります。
react-feather のアイコンは、size、color、strokeWidthなどのプロパティで簡単に調整できます。CSSで上書きすることも可能です。
react-fontawesome は、size、color、spin、flipなど豊富なプロパティを提供しており、アニメーションや回転といった高度な操作も簡単に行えます。
react-icons の各アイコンは、共通のインターフェース(size, color, classNameなど)を持ち、スタイルの一貫性を保ちつつ柔軟にカスタマイズできます。
react-svg は、読み込まれたSVG要素に対して直接CSSを適用できるため、最も自由度が高いです。ただし、SVG内のfillやstroke属性がインラインで定義されている場合、CSSで上書きするには!importantやcurrentColorの活用が必要になることがあります。
react-feather: シンプルで直感的。アイコン名がコンポーネント名になるため、IDEのオートコンプリートが効きやすい。react-fontawesome: 設定ステップが多いが、公式ドキュメントが充実しており、Proアイコンとの連携もスムーズ。react-icons: 複数のアイコンセットを横断して使えるため、チーム内で「どのアイコンセットを使うか」の議論を避けたい場合に最適。新しいアイコンを探すのも容易。react-svg: カスタムSVGを大量に扱うプロジェクト(例:デザインシステム内製アイコン)に向いているが、型安全性や静的解析が難しい点に注意。react-fontawesome を使う際、library.add()を使わずに直接インポートする方式(Explicit Import)が現在推奨されています。古い方法を使うと不要なコードがバンドルされる可能性があります。
react-svg は、SVGファイルの内容を信頼できないソースから読み込む場合、XSSのリスクがあるため注意が必要です。また、CSP(Content Security Policy)の設定によっては読み込みがブロックされることもあります。
react-icons はアイコンセットのバージョンを内部で固定しているため、特定のアイコンセットの最新機能を使いたい場合は、そのアイコンセットの単体パッケージを使う方が良い場合があります。
| パッケージ | 向いているケース | 注意点 |
|---|---|---|
react-feather | Feather Iconsが気に入っていて、シンプルで軽量なアイコンが必要な場合 | アイコンセットが固定されている |
react-fontawesome | Font Awesomeの豊富なアイコンやアニメーション機能が必要な場合 | 設定がやや複雑。Pro版を使うならライセンス確認必須 |
react-icons | 複数のアイコンセットから自由に選べる柔軟性が欲しい場合 | 各アイコンセットの細かいカスタマイズには制限あり |
react-svg | カスタムSVGアセットを動的に読み込む必要がある場合 | ネットワークリクエストが発生。セキュリティとパフォーマンスに注意 |
最終的には、プロジェクトの規模、デザイン要件、チームのワークフローに合わせて選ぶのがベストです。小規模プロジェクトならreact-featherやreact-iconsの一部セットで十分ですが、大規模アプリやデザインシステムではreact-svgによる柔軟なアセット管理が有利になることもあります。
react-iconsは、複数のアイコンセット(Feather、FontAwesome、Material Iconsなど)から自由に選べる柔軟性が欲しい場合に最適です。特に、チーム内で「どのアイコンを使うか」を都度決めたい、または既存のデザインガイドに合わせてアイコンセットを切り替えたいプロジェクトに向いています。Tree Shakingも効くため、バンドルサイズも抑えられます。
react-featherは、Feather Iconsのシンプルで一貫性のあるデザインを気に入っており、軽量かつTree Shaking対応のアイコンコンポーネントが欲しい場合に最適です。小規模〜中規模のアプリで、アイコンの種類を限定したいプロジェクトに向いています。ただし、他のアイコンセットを使いたい場合は選択肢になりません。
react-svgは、カスタムSVGアセット(例:社内デザインシステムで作成された独自アイコン)を動的にReactコンポーネントとして読み込む必要がある場合に選んでください。外部SVGファイルを直接扱えるため柔軟性は高いですが、ネットワークリクエストが発生するためパフォーマンスやセキュリティ(XSSリスク)に注意が必要です。
react-fontawesomeは、Font Awesomeの豊富なアイコンライブラリ(特にPro版)や、回転・アニメーションなどの高度な機能が必要な場合に選んでください。公式サポートがあり、商用プロジェクトでも安心して使えますが、初期設定がやや複雑で、不要なアイコンがバンドルに含まれないよう注意が必要です。
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