@radix-ui/react-icons vs heroicons vs react-icons
Icon Library Strategies for React Applications
@radix-ui/react-iconsheroiconsreact-iconsSimilar Packages:

Icon Library Strategies for React Applications

@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.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
@radix-ui/react-icons0-3.44 MB-a year agoMIT
heroicons023,439700 kB3a year agoMIT
react-icons012,53287 MB246a month agoMIT

Icon Library Strategies for React Applications

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.

📦 Installation and Import Patterns

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.

  • You install one package and import any icon directly.
  • No need to know which set the icon belongs to.
// @radix-ui/react-icons
import { ArrowRightIcon } from '@radix-ui/react-icons';

function Button() {
  return <ArrowRightIcon />;
}

react-icons organizes icons by their original source set.

  • You must import from a specific sub-path (like hi for Heroicons or fa for FontAwesome).
  • This keeps tree shaking efficient but requires knowing the source.
// react-icons
import { HiArrowRight } from 'react-icons/hi';

function Button() {
  return <HiArrowRight />;
}

heroicons is primarily an SVG asset library.

  • The official React usage often involves copying the JSX from their website or importing SVG files.
  • This gives you full control but requires more manual work than a direct component import.
// 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>
  );
}

🌲 Tree Shaking and Bundle Size

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.

  • Each icon is a separate named export.
  • Bundlers like Webpack or Vite automatically remove icons you don't use.
// @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.

  • You must import icons individually, not the whole set.
  • Importing the whole set will bloat your bundle.
// 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.

  • If you copy JSX, only the used SVG code is in your bundle.
  • If you import SVG files, your bundler must be configured to tree shake assets.
// 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';

🎨 Styling and Customization

Icons often need to change color or size based on context. Each library handles props differently.

@radix-ui/react-icons accepts standard SVG props.

  • You can pass className, width, height, or fill directly.
  • Works naturally with Tailwind or CSS modules.
// @radix-ui/react-icons
<ArrowRightIcon className="w-6 h-6 text-blue-500" />

react-icons also passes props to the underlying SVG.

  • You can style them exactly like regular HTML elements.
  • Size is often controlled via 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.

  • Since you own the JSX, you can modify any attribute directly.
  • No wrapper props to learn, just standard SVG attributes.
// heroicons
<ArrowRightIcon className="w-6 h-6 text-blue-500" />
// Or modify SVG directly
<svg className="w-6 h-6" fill="none" ...>

🧩 Design System Consistency

Consistency matters when your app grows. Mixing icon styles can make the UI feel disjointed.

@radix-ui/react-icons enforces a strict 15x15 grid.

  • All icons are designed to align perfectly with Radix UI components.
  • Best for apps using Radix primitives like Dialogs or Menus.
// @radix-ui/react-icons
// Consistent visual weight across all icons
<ArrowRightIcon />
<CheckIcon />

react-icons mixes many design languages.

  • You can use Material icons next to FontAwesome icons.
  • Great for variety, but requires discipline to keep things uniform.
// react-icons
// Potential mismatch if not careful
<HiArrowRight /> // Heroicons style
<FaFacebook />   // FontAwesome style

heroicons matches Tailwind CSS perfectly.

  • Designed by the same team to work together.
  • Ideal for projects where Tailwind is the core styling engine.
// heroicons
// Matches Tailwind utility classes naturally
<svg className="stroke-current" ... />

🛠️ Maintenance and Updates

Keeping icons up to date can be a hidden cost. Some libraries make this easier than others.

@radix-ui/react-icons updates via npm.

  • You run npm update and get new icons or fixes.
  • No manual code changes needed.
// @radix-ui/react-icons
// Update via package manager
npm install @radix-ui/react-icons@latest

react-icons also updates via npm.

  • One command updates all icon sets included in the library.
  • Very low maintenance overhead.
// react-icons
// Update via package manager
npm install react-icons@latest

heroicons may require manual updates if copying JSX.

  • If you copy SVG code, you must check for updates manually.
  • If you import SVGs, npm updates work normally.
// heroicons
// If copying JSX, you must manually check for updates
// If using npm package:
npm install heroicons@latest

📊 Summary Table

Feature@radix-ui/react-iconsreact-iconsheroicons
TypeReact ComponentsReact ComponentsSVG Assets
ImportNamed ExportNamed Export (Sub-path)JSX Copy or SVG Import
Tree ShakingAutomaticManual (Per Icon)Depends on Integration
Design15x15 GridMixed SetsTailwind Match
SetupZero ConfigZero ConfigManual or Loader

💡 Final Recommendation

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).

How to Choose: @radix-ui/react-icons vs heroicons vs react-icons

  • @radix-ui/react-icons:

    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.

  • heroicons:

    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.

  • react-icons:

    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.

README for @radix-ui/react-icons

Radix Icons

A crisp set of 15×15 icons designed by the WorkOS team.

Visit icons.radix-ui.com to browse the icons.


Documentation

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>
  );
}

Contributing

Please follow our contributing guidelines.

Authors

License

Licensed under the MIT License, Copyright © 2022-present WorkOS.

See LICENSE for more information.