@radix-ui/react-icons, heroicons, and react-icons are three popular ways to add icons to React projects, but they serve different architectural needs. @radix-ui/react-icons provides a focused set of 15x15 pixel icons designed to work seamlessly with Radix UI primitives. heroicons is the official SVG icon set from the creators of Tailwind CSS, primarily distributed as SVG assets that integrate closely with Tailwind utilities. react-icons acts as a unified aggregator, offering thousands of icons from many different sets (like FontAwesome, Material Design, and more) through a single consistent React API.
Adding icons to a React app seems simple, but the choice of library affects your bundle size, design consistency, and maintenance workflow. @radix-ui/react-icons, heroicons, and react-icons take three different approaches to solving this problem. Let's break down how they work in real engineering scenarios.
The way you bring icons into your code varies significantly between these packages. This affects how easy they are to use and how much setup they require.
@radix-ui/react-icons uses direct named exports from a single package.
// @radix-ui/react-icons
import { ArrowRightIcon } from '@radix-ui/react-icons';
function Button() {
return <ArrowRightIcon />;
}
react-icons organizes icons by their original source set.
hi for Heroicons or fa for FontAwesome).// react-icons
import { HiArrowRight } from 'react-icons/hi';
function Button() {
return <HiArrowRight />;
}
heroicons is primarily an SVG asset library.
// heroicons
// Common pattern: Copy JSX from heroicons.com into your component
function ArrowRightIcon(props) {
return (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" {...props}>
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3" />
</svg>
);
}
All three libraries support tree shaking, but they achieve it differently. This impacts how much unused code ends up in your final build.
@radix-ui/react-icons is built for automatic tree shaking.
// @radix-ui/react-icons
// Only ArrowRightIcon is included in the bundle
import { ArrowRightIcon } from '@radix-ui/react-icons';
react-icons relies on ES modules for tree shaking.
// react-icons
// ✅ Good: Only HiArrowRight is included
import { HiArrowRight } from 'react-icons/hi';
// ❌ Bad: Includes all Heroicons
// import * as Hi from 'react-icons/hi';
heroicons depends on how you integrate the SVGs.
// heroicons
// ✅ Good: Only this SVG code exists in your file
function ArrowRightIcon(props) { /* SVG JSX */ }
// ❌ Bad: Loading all SVGs if using a context loader without care
// import allIcons from './heroicons/all';
Icons often need to change color or size based on context. Each library handles props differently.
@radix-ui/react-icons accepts standard SVG props.
className, width, height, or fill directly.// @radix-ui/react-icons
<ArrowRightIcon className="w-6 h-6 text-blue-500" />
react-icons also passes props to the underlying SVG.
size prop or CSS.// react-icons
<HiArrowRight className="w-6 h-6 text-blue-500" />
// Or
<HiArrowRight size={24} color="blue" />
heroicons gives you raw SVG control.
// heroicons
<ArrowRightIcon className="w-6 h-6 text-blue-500" />
// Or modify SVG directly
<svg className="w-6 h-6" fill="none" ...>
Consistency matters when your app grows. Mixing icon styles can make the UI feel disjointed.
@radix-ui/react-icons enforces a strict 15x15 grid.
// @radix-ui/react-icons
// Consistent visual weight across all icons
<ArrowRightIcon />
<CheckIcon />
react-icons mixes many design languages.
// react-icons
// Potential mismatch if not careful
<HiArrowRight /> // Heroicons style
<FaFacebook /> // FontAwesome style
heroicons matches Tailwind CSS perfectly.
// heroicons
// Matches Tailwind utility classes naturally
<svg className="stroke-current" ... />
Keeping icons up to date can be a hidden cost. Some libraries make this easier than others.
@radix-ui/react-icons updates via npm.
npm update and get new icons or fixes.// @radix-ui/react-icons
// Update via package manager
npm install @radix-ui/react-icons@latest
react-icons also updates via npm.
// react-icons
// Update via package manager
npm install react-icons@latest
heroicons may require manual updates if copying JSX.
// heroicons
// If copying JSX, you must manually check for updates
// If using npm package:
npm install heroicons@latest
| Feature | @radix-ui/react-icons | react-icons | heroicons |
|---|---|---|---|
| Type | React Components | React Components | SVG Assets |
| Import | Named Export | Named Export (Sub-path) | JSX Copy or SVG Import |
| Tree Shaking | Automatic | Manual (Per Icon) | Depends on Integration |
| Design | 15x15 Grid | Mixed Sets | Tailwind Match |
| Setup | Zero Config | Zero Config | Manual or Loader |
Think about your design system and workflow first.
@radix-ui/react-icons is the best fit if you use Radix UI primitives. It ensures your icons align perfectly with your accessible components without extra work.
react-icons wins when you need variety. If your app requires specific branded icons or you want one import style for everything, this is the most efficient choice.
heroicons is the top choice for Tailwind CSS projects. If you want icons that feel native to Tailwind and don't mind copying JSX or configuring SVG imports, it offers the best visual integration.
Final Thought: All three libraries are solid choices. The right one depends on whether you prioritize design system alignment (@radix-ui/react-icons), variety (react-icons), or Tailwind integration (heroicons).
Choose @radix-ui/react-icons if you are already using Radix UI primitives and want icons that match the 15x15 grid system exactly. It is ideal for building accessible, consistent design systems with minimal setup and zero configuration for tree shaking.
Choose heroicons if your project relies heavily on Tailwind CSS and you want icons that match the Tailwind design language perfectly. It is best for teams willing to copy JSX snippets or configure SVG loaders to get exact visual control without extra component wrappers.
Choose react-icons if you need access to a wide variety of icon sets without installing multiple packages. It is suitable for projects that require specific branded icons (like social media logos) or when you want a single import pattern for all icons regardless of their source.
A crisp set of 15×15 icons designed by the WorkOS team.
Visit icons.radix-ui.com to browse the icons.
All icons are available as individual React components.
Install Radix Icons from npm:
npm install @radix-ui/react-icons
Import the icons into your React project:
import { FaceIcon, ImageIcon, SunIcon } from '@radix-ui/react-icons';
function MyComponent() {
return (
<div>
<FaceIcon />
<SunIcon />
<ImageIcon />
</div>
);
}
Please follow our contributing guidelines.
Licensed under the MIT License, Copyright © 2022-present WorkOS.
See LICENSE for more information.