React Icons
Recipe
Instala React Icons para acceder a miles de ícones de familias de ícones populares a través de un único paquete. Cada familia de ícones utiliza un prefijo de dos letras y su propia ruta de importación para tree-shaking.
npm install react-icons// app/components/icon-sampler.tsx
"use client";
import { FaGithub, FaTwitter } from "react-icons/fa";
import { MdEmail, MdSettings } from "react-icons/md";
import { HiOutlineSearch } from "react-icons/hi";
import { FiMenu } from "react-icons/fi";
export function IconSampler() {
return (
<div className="flex items-center gap-4 text-2xl">
<FaGithub />
<FaTwitter className="text-blue-400" />
<MdEmail className="text-red-500" />
<MdSettings className="text-gray-600" />
<HiOutlineSearch />
<FiMenu />
</div>
);
}Conjuntos de Ícones Disponibles
| Prefijo | Conjunto de Ícones | Cantidad de Ícones | Estilo |
|---|---|---|---|
| Fa | Font Awesome 5 | 1,600+ | Sólido y regular |
| Fa6 | Font Awesome 6 | 2,000+ | Sólido, regular, marcas |
| Md | Material Design | 4,300+ | Relleno y delineado |
| Hi | Heroicons v1 | 450+ | Contorno y sólido |
| Hi2 | Heroicons v2 | 600+ | Contorno, sólido, mini |
| Fi | Feather Icons | 280+ | Basado en trazo |
| Bs | Bootstrap Icons | 1,800+ | Relleno y contorno |
| Ai | Ant Design | 780+ | Relleno y delineado |
| Si | Simple Icons (marcas) | 2,500+ | Logos de marca |
| Tb | Tabler Icons | 4,600+ | Basado en trazo |
| Lu | Lucide | 1,400+ | Basado en trazo |
Ejemplo Funcional
Una barra de enlaces de redes sociales utilizando ícones de múltiples familias:
// app/components/social-links.tsx
"use client";
import { FaGithub, FaLinkedinIn, FaYoutube } from "react-icons/fa";
import { FaXTwitter } from "react-icons/fa6";
import { SiBluesky, SiDiscord } from "react-icons/si";
import { IconContext } from "react-icons";
interface SocialLink {
href: string;
icon: React.ElementType;
label: string;
hoverColor: string;
}
const socialLinks: SocialLink[] = [
{ href: "https://github.com/username", icon: FaGithub, label: "GitHub", hoverColor: "hover:text-gray-900" },
{ href: "https://x.com/username", icon: FaXTwitter, label: "X (Twitter)", hoverColor: "hover:text-black" },
{ href: "https://linkedin.com/in/username", icon: FaLinkedinIn, label: "LinkedIn", hoverColor: "hover:text-blue-700" },
{ href: "https://youtube.com/@username", icon: FaYoutube, label: "YouTube", hoverColor: "hover:text-red-600" },
{ href: "https://bsky.app/profile/username", icon: SiBluesky, label: "Bluesky", hoverColor: "hover:text-blue-500" },
{ href: "https://discord.gg/invite", icon: SiDiscord, label: "Discord", hoverColor: "hover:text-indigo-500" },
];
export function SocialLinksBar() {
return (
<IconContext.Provider value={{ size: "1.5rem" }}>
<nav aria-label="Social media links" className="flex items-center gap-6">
{socialLinks.map(({ href, icon: Icon, label, hoverColor }) => (
<a
key={label}
href={href}
target="_blank"
rel="noopener noreferrer"
aria-label={label}
className={`text-gray-500 transition-colors ${hoverColor}`}
>
<Icon />
</a>
))}
</nav>
</IconContext.Provider>
);
}Análisis Profundo
Cómo Funciona
- React Icons agrupa muchas librerías de ícones en un único paquete npm pero las organiza por ruta de importación (
react-icons/fa,react-icons/md, etc.). - Cada ruta de importación corresponde a una familia de ícones, y los empaquetadores realizan tree-shaking de ícones no utilizados dentro de esa familia.
- Los ícones se renderizan como elementos SVG inline. Heredan
font-sizeycolorde su padre por defecto (usando1emycurrentColor). IconContext.Providerte permite establecersize,color,classNameystylepor defecto para todos los ícones descendientes sin repetir props.
Variaciones
Estilo global con IconContext:
import { IconContext } from "react-icons";
export function IconProvider({ children }: { children: React.ReactNode }) {
return (
<IconContext.Provider
value={{
size: "1.25rem",
className: "inline-block align-middle",
style: { verticalAlign: "middle" },
}}
>
{children}
</IconContext.Provider>
);
}Comparando el impacto del tamaño del paquete:
// BUENO: importa solo FaGithub (~1KB)
import { FaGithub } from "react-icons/fa";
// MALO: aún importa solo FaGithub, pero algunas configuraciones de empaquetador más antiguas
// pueden no realizar tree-shaking correctamente
import { FaGithub } from "react-icons";Siempre importa desde la ruta de familia específica (react-icons/fa) en lugar de la raíz del paquete.
Notas de TypeScript
- Todos los ícones están tipados como
React.ComponentType<IconBaseProps>. IconBasePropsextiendeSVGAttributes<SVGElement>y añadesize,color,titleyclassName.IconContextestá tipado comoReact.Context<IconBaseProps>.
import type { IconType } from "react-icons";
interface NavItem {
icon: IconType;
label: string;
href: string;
}Gotchas
- Importar desde
react-icons(la raíz) en lugar de una subruta comoreact-icons/fapuede empaquetar la librería completa en algunas configuraciones. Siempre usa la ruta de importación específica de la familia. - Las diferentes familias de ícones tienen diferentes tamaños por defecto y pesos visuales. Un ícono de Font Awesome junto a un ícono de Feather puede verse desajustado sin dimensionamiento explícito.
IconContextusa React Context, por lo que el componente proveedor debe ser un Client Component en Next.js App Router.- Algunas familias de ícones incluyen solo variantes rellenas (Font Awesome sólido) mientras que otras se basan en trazo (Feather). Mezclar estilos puede verse inconsistente.
- El prop
sizeacepta una cadena (como"1.5rem") o número. Cuando se usa un número, se asigna a píxeles.
Alternativas
| Enfoque | Ventajas | Desventajas |
|---|---|---|
| React Icons | Un paquete para muchas familias de ícones | Tamaño de instalación grande en disco, potencial inflación de paquete |
| Lucide React | Mejor tree-shaking, estilo consistente | Solo un estilo de ícono |
| Librería de ícones directa (@heroicons/react) | Paquete oficial, integración más estricta | Solo una familia de ícones por paquete |
| Sprites SVG | Paquete más pequeño posible | Configuración manual, sin API de componente |
FAQs
¿Cómo importas ícones de diferentes familias en React Icons?
Cada familia tiene su propia ruta de importación usando un prefijo de dos letras:
import { FaGithub } from "react-icons/fa"; // Font Awesome
import { MdEmail } from "react-icons/md"; // Material Design
import { HiOutlineSearch } from "react-icons/hi"; // Heroicons¿Qué hace IconContext.Provider y dónde debe colocarse?
- Establece
size,color,classNameystylepor defecto para todos los ícones descendientes. - Usa React Context, por lo que debe ser un Client Component en Next.js App Router.
- Envuélvelo alrededor de cualquier subárbol donde desees estilo de ícono consistente.
Gotcha: ¿Qué sucede si importas desde react-icons en lugar de react-icons/fa?
- Importar desde la raíz del paquete en lugar de una subruta puede empaquetar la librería completa en algunas configuraciones.
- Siempre usa la ruta específica de la familia (p. ej.,
react-icons/fa,react-icons/md) para tree-shaking adecuado.
¿Cómo heredan los ícones de React su tamaño y color por defecto?
- Los ícones se renderizan como SVGs inline usando
1empara tamaño ycurrentColorpara color. - Heredan
font-sizeycolorde su elemento padre automáticamente.
¿Por qué los ícones de diferentes familias pueden verse desajustados cuando se colocan lado a lado?
- Las diferentes familias tienen diferentes tamaños por defecto y pesos visuales.
- Los ícones de Font Awesome son rellenos; los ícones de Feather se basan en trazo.
- Usa dimensionamiento explícito y familias consistentes, o normaliza con
IconContext.
¿Qué tipo de TypeScript debes usar para un ícono de React Icons pasado como prop?
import type { IconType } from "react-icons";
interface NavItem {
icon: IconType;
label: string;
href: string;
}IconType es equivalente a React.ComponentType<IconBaseProps>.
¿Qué es IconBaseProps y qué extiende?
IconBasePropsextiendeSVGAttributes<SVGElement>.- Añade propiedades
size,color,titleyclassName. IconContextestá tipado comoReact.Context<IconBaseProps>.
¿Cómo estableces un tamaño de ícono global y alineación vertical para todos los ícones?
<IconContext.Provider
value={{
size: "1.25rem",
className: "inline-block align-middle",
style: { verticalAlign: "middle" },
}}
>
{children}
</IconContext.Provider>¿El prop size acepta cadenas, números, o ambos?
- Acepta tanto cadenas (p. ej.,
"1.5rem") como números. - Cuando se usa un número, se asigna a píxeles.
Gotcha: ¿Puedes mezclar familias de ícones rellenos y basados en trazo sin problemas visuales?
- No. Mezclar estilos (p. ej., Font Awesome sólido con Feather stroke) se ve inconsistente.
- Adhiérete a una familia de ícones para un peso visual consistente, o normaliza cuidadosamente los tamaños y trazos.
¿Cuántas familias de ícones incluye React Icons y cuál tiene más ícones?
- React Icons incluye 11+ familias de ícones en un único paquete.
- Tabler Icons (prefijo
Tb) tiene la mayoría con 4,600+ ícones. - Material Design (
Md) le sigue con 4,300+ ícones.