react-feather 和 react-icons 都是为 React 应用提供矢量图标的流行 npm 包,但它们在图标来源、API 设计和使用方式上有显著差异。react-feather 专注于 Feather Icons 这一单一图标集,提供简洁一致的 API;而 react-icons 是一个聚合型图标库,整合了包括 Feather、FontAwesome、Material Design 等数十个主流图标集,通过统一的导入方式暴露所有图标。两者都支持按需引入、自定义样式(如颜色、大小)和 TypeScript 类型支持,适用于需要在 React 组件中嵌入 SVG 图标的各类项目。
在 React 项目中引入图标看似简单,但选型不当可能导致 bundle 体积膨胀、维护成本上升或设计一致性受损。react-feather 和 react-icons 是两个主流选择,但它们的设计哲学和适用场景截然不同。本文从工程实践角度,深入剖析两者的异同。
react-feather 仅包含 Feather Icons 这一开源图标集。Feather 以 24×24 像素、单色、线条风格著称,共 280+ 个图标,风格高度统一,适合追求极简美学的界面。
// react-feather:仅限 Feather 图标
import { Heart, User, Settings } from 'react-feather';
function App() {
return (
<div>
<Heart color="red" />
<User size={20} />
<Settings />
</div>
);
}
react-icons 则是一个“图标超市”,聚合了包括 Feather、FontAwesome、Material Design、Ionicons 等 30+ 个 主流图标库。每个图标集通过独立的命名空间导出,例如 Feather 图标位于 Fi 前缀下。
// react-icons:多图标集混合使用
import { FiHeart, FaUser, MdSettings } from 'react-icons';
function App() {
return (
<div>
<FiHeart color="red" />
<FaUser size={20} />
<MdSettings />
</div>
);
}
💡 关键区别:
react-feather是“专卖店”,react-icons是“百货商场”。前者专注单一风格,后者提供广泛选择。
两者都基于 React 组件封装 SVG,支持通过 props 自定义 size、color、className 等属性,但命名约定不同。
react-feather 的组件名直接对应图标名(PascalCase),无前缀:
import { Activity, CloudRain } from 'react-feather';
<Activity size={24} color="#000" />
<CloudRain className="custom-icon" />
react-icons 为每个图标集分配固定前缀(如 Feather 为 Fi,FontAwesome 为 Fa),组件名也采用 PascalCase:
import { FiActivity, FiCloudRain } from 'react-icons/fi'; // 注意:需指定子路径
<FiActivity size={24} color="#000" />
<FiCloudRain className="custom-icon" />
⚠️ 注意:
react-icons要求从具体子路径导入(如react-icons/fi),否则会引入整个库,导致 bundle 体积剧增。这是新手常犯的错误。
两者均支持 按需引入(tree-shaking),但实际效果取决于使用方式。
react-feather:由于只包含一个图标集,即使错误地全量导入(import * as Feather from 'react-feather'),最大体积也有限(约 50KB minified)。正确按需引入后,每个图标仅增加 ~150 字节。
react-icons:若从根路径导入(import { FiHeart } from 'react-icons'),Webpack 可能无法有效 tree-shake,导致整个 Feather 图标集(甚至更多)被打包。必须从子路径导入(import { FiHeart } from 'react-icons/fi')才能确保只包含所需图标。
// ✅ 正确:react-icons 按需引入
import { FiHeart } from 'react-icons/fi'; // 仅包含 Heart 图标
// ❌ 错误:可能引入整个 Feather 图标集
import { FiHeart } from 'react-icons';
两者在样式定制上能力相当,均通过 props 控制 SVG 属性:
| 属性 | 作用 | 示例值 |
|---|---|---|
size | 设置图标宽高 | 24, '1.5em', '2rem' |
color | 设置填充/描边颜色 | '#ff0000', 'currentColor' |
className | 添加 CSS 类 | 'icon-primary' |
style | 内联样式 | { opacity: 0.8 } |
// 两者均支持以下写法
<Icon size={32} color="blue" className="hover-effect" style={{ marginRight: '8px' }} />
💡 提示:推荐使用
color="currentColor"配合父元素文本颜色,实现自动主题适配。
两者均提供完整的 TypeScript 类型定义,组件 props 类型明确:
// react-feather 类型示意
interface IconProps extends React.SVGProps<SVGSVGElement> {
size?: string | number;
color?: string;
}
// react-icons 类型类似,额外继承 SVGProps
开发者可获得良好的 IDE 自动补全和类型检查,无需额外配置。
react-feather:API 更简洁,无多余依赖,bundle 更可控。react-icons 造成间接依赖膨胀。react-icons:react-feather 无法满足需求。webpack-bundle-analyzer)防止意外全量引入。react-feather(单一图标集上限低)。| 维度 | react-feather | react-icons |
|---|---|---|
| 图标来源 | 仅 Feather Icons | 30+ 图标集(含 Feather、FA、MD 等) |
| 导入方式 | import { Icon } from 'react-feather' | import { FiIcon } from 'react-icons/fi' |
| Bundle 风险 | 低(单一集上限固定) | 高(错误导入会引入整个图标集) |
| 适用场景 | 单一风格、轻量项目 | 多风格混合、大型应用 |
| 学习成本 | 极低 | 需记忆各图标集前缀(如 Fi, Fa, Md) |
react-icons。YAGNI(You Aren't Gonna Need It)原则在此适用——先用 react-feather,等真有需求再迁移。react-icons,务必审计导入路径。运行 npm ls react-icons 并检查打包报告,确保没有意外全量引入。无论选择哪个库,记住:图标是 UI 的细节,但细节决定专业度。
选择 react-feather 如果你只需要 Feather Icons 这一套风格统一、轻量简洁的图标,并希望获得最直接的 API 体验。它适合对 bundle size 敏感、且设计系统已确定采用 Feather 风格的项目,避免引入不必要的图标集依赖。
选择 react-icons 如果你需要灵活使用多个图标库(如同时用 Feather 和 Material Icons),或尚未确定最终图标方案。它通过统一的命名和导入方式简化了多图标集的管理,适合需要快速原型验证或支持多种设计语言的大型应用。
react-feather is a collection of simply beautiful open source icons for React.js. Each icon is designed on a 24x24 grid with an emphasis on simplicity, consistency and readability.
v4.28.0yarn add react-feather
or
npm i react-feather
import React from 'react';
import { Camera } from 'react-feather';
const App = () => {
return <Camera />
};
export default App;
Icons can be configured with inline props:
<Camera color="red" size={48} />
If you can't use ES6 imports, it's possible to include icons from the compiled folder ./dist.
var Camera = require('react-feather/dist/icons/camera').default;
var MyComponent = React.createClass({
render: function () {
return (
<Camera />
);
}
});
You can also include the whole icon pack:
import React from 'react';
import * as Icon from 'react-feather';
const App = () => {
return <Icon.Camera />
};
export default App;