Icon Design
Select the right icon for the job. Maps concepts to icons across three modern libraries, provides ready-to-use templates, and prevents common mistakes like broken tree-shaking and inconsistent styles.
Quick Reference
| Concept |
Lucide |
Heroicons |
Phosphor |
| Award/Quality |
Trophy |
trophy |
Trophy |
| Price/Value |
Tag |
tag |
Tag |
| Location |
MapPin |
map-pin |
MapPin |
| Expertise |
GraduationCap |
academic-cap |
GraduationCap |
| Support |
MessageCircle |
chat-bubble-left-right |
ChatCircle |
| Security |
Shield |
shield-check |
Shield |
| Speed |
Zap |
bolt |
Lightning |
| Phone |
Phone |
phone |
Phone |
| Email |
Mail |
envelope |
Envelope |
| User/Profile |
User |
user |
User |
| Team |
Users |
user-group |
Users |
| Settings |
Settings |
cog-6-tooth |
Gear |
| Home |
Home |
home |
House |
| Search |
Search |
magnifying-glass |
MagnifyingGlass |
| Check/Success |
Check |
check |
Check |
| Close/Cancel |
X |
x-mark |
X |
| Menu |
Menu |
bars-3 |
List |
| Calendar |
Calendar |
calendar |
Calendar |
| Clock/Time |
Clock |
clock |
Clock |
| Heart/Favorite |
Heart |
heart |
Heart |
Library Selection
| Library |
Best For |
Package |
| Lucide |
General use, React projects |
lucide-react |
| Heroicons |
Tailwind projects, minimal style |
@heroicons/react |
| Phosphor |
Weight variations needed |
@phosphor-icons/react |
Default recommendation: Lucide (1,600+ icons, excellent React integration, dynamic loading via lucide-react/dynamic).
Selection Process
- Identify the concept -- what does the label/title communicate?
- Check semantic mapping -- see
references/semantic-mapping.md
- Choose library -- Lucide (default), Heroicons (Tailwind), Phosphor (weights)
- Apply template -- see
references/icon-templates.md
- Verify consistency -- same style, same size within each section
Icon Style Rules
| Rule |
Detail |
| No mixed styles |
Use all outline OR all solid in a section |
| No emoji |
Use proper icon components (tree-shakeable) |
| Use currentColor |
Icons inherit text color via stroke="currentColor" |
| Semantic colors |
Use text-primary, not text-blue-500 |
| Consistent sizing |
Inline w-4 h-4, cards w-8 h-8, hero w-10 h-10 |
| Tree-shaking safe |
Use explicit named imports and icon maps, never import * |
| Accessibility |
Add aria-hidden="true" to decorative icons, aria-label to buttons |
Common Mistakes
| Mistake |
Correct Pattern |
Importing all icons with import * as Icons breaking tree-shaking |
Use explicit named imports and a static icon map |
| Mixing outline and solid icon styles within the same section |
Pick one style per section and apply consistently |
| Using emoji instead of proper icon components |
Always use tree-shakeable icon components from Lucide, Heroicons, or Phosphor |
Hardcoding color values like text-blue-500 on icons |
Use semantic colors like text-primary so icons inherit theme changes |
| Choosing icons by visual appeal rather than semantic meaning |
Map the concept first using the semantic mapping reference, then select the icon |
Missing aria-label on icon-only buttons |
Add aria-label="Description" to buttons containing only icons |
| Using old Heroicons import paths without size prefix |
Use @heroicons/react/24/outline with the size prefix |
Delegation
- Audit existing icon usage for consistency and tree-shaking issues: Use
Explore agent to scan imports and identify mixed styles or wildcard imports
- Migrate icons from Font Awesome or Material to modern libraries: Use
Task agent with the migration guide reference
- Plan icon system architecture for a design system: Use
Plan agent to select library, define sizing conventions, and establish semantic mappings
References
- semantic-mapping.md -- Full concept-to-icon tables by category (quality, price, location, trade-specific, navigation, status)
- icon-templates.md -- React/HTML patterns with Tailwind (feature cards, buttons, inputs, navigation, status badges)
- library-comparison.md -- Lucide vs Heroicons vs Phosphor (features, bundle size, import patterns)
- migration-guide.md -- Font Awesome, Material Icons, Feather, and emoji to modern equivalents
- accessibility.md -- Decorative vs meaningful icons, aria attributes, screen reader patterns
1---2name: icon-design3description: Select semantically appropriate icons for websites using Lucide, Heroicons, or Phosphor. Covers concept-to-icon mapping, React/HTML templates, and tree-shaking patterns. Use when: building feature sections, service grids, contact info, navigation, or any UI needing icons. Prevents emoji usage, ensures consistency.4license: MIT5---6
7# Icon Design
8
9Select the right icon for the job. Maps concepts to icons across three modern libraries, provides ready-to-use templates, and prevents common mistakes like broken tree-shaking and inconsistent styles.
10
11## Quick Reference
12
13| Concept | Lucide | Heroicons | Phosphor |
14| -------------- | --------------- | ------------------------ | ----------------- |
15| Award/Quality | `Trophy` | `trophy` | `Trophy` |
16| Price/Value | `Tag` | `tag` | `Tag` |
17| Location | `MapPin` | `map-pin` | `MapPin` |
18| Expertise | `GraduationCap` | `academic-cap` | `GraduationCap` |
19| Support | `MessageCircle` | `chat-bubble-left-right` | `ChatCircle` |
20| Security | `Shield` | `shield-check` | `Shield` |
21| Speed | `Zap` | `bolt` | `Lightning` |
22| Phone | `Phone` | `phone` | `Phone` |
23| Email | `Mail` | `envelope` | `Envelope` |
24| User/Profile | `User` | `user` | `User` |
25| Team | `Users` | `user-group` | `Users` |
26| Settings | `Settings` | `cog-6-tooth` | `Gear` |
27| Home | `Home` | `home` | `House` |
28| Search | `Search` | `magnifying-glass` | `MagnifyingGlass` |
29| Check/Success | `Check` | `check` | `Check` |
30| Close/Cancel | `X` | `x-mark` | `X` |
31| Menu | `Menu` | `bars-3` | `List` |
32| Calendar | `Calendar` | `calendar` | `Calendar` |
33| Clock/Time | `Clock` | `clock` | `Clock` |
34| Heart/Favorite | `Heart` | `heart` | `Heart` |
35
36## Library Selection
37
38| Library | Best For | Package |
39| ------------- | -------------------------------- | ----------------------- |
40| **Lucide** | General use, React projects | `lucide-react` |
41| **Heroicons** | Tailwind projects, minimal style | `@heroicons/react` |
42| **Phosphor** | Weight variations needed | `@phosphor-icons/react` |
43
44Default recommendation: Lucide (1,600+ icons, excellent React integration, dynamic loading via `lucide-react/dynamic`).
45
46## Selection Process
47
481. **Identify the concept** -- what does the label/title communicate?
492. **Check semantic mapping** -- see `references/semantic-mapping.md`
503. **Choose library** -- Lucide (default), Heroicons (Tailwind), Phosphor (weights)
514. **Apply template** -- see `references/icon-templates.md`
525. **Verify consistency** -- same style, same size within each section
53
54## Icon Style Rules
55
56| Rule | Detail |
57| ----------------- | --------------------------------------------------------------------- |
58| No mixed styles | Use all outline OR all solid in a section |
59| No emoji | Use proper icon components (tree-shakeable) |
60| Use currentColor | Icons inherit text color via `stroke="currentColor"` |
61| Semantic colors | Use `text-primary`, not `text-blue-500` |
62| Consistent sizing | Inline `w-4 h-4`, cards `w-8 h-8`, hero `w-10 h-10` |
63| Tree-shaking safe | Use explicit named imports and icon maps, never `import *` |
64| Accessibility | Add `aria-hidden="true"` to decorative icons, `aria-label` to buttons |
65
66## Common Mistakes
67
68| Mistake | Correct Pattern |
69| ------------------------------------------------------------------ | -------------------------------------------------------------------------------- |
70| Importing all icons with `import * as Icons` breaking tree-shaking | Use explicit named imports and a static icon map |
71| Mixing outline and solid icon styles within the same section | Pick one style per section and apply consistently |
72| Using emoji instead of proper icon components | Always use tree-shakeable icon components from Lucide, Heroicons, or Phosphor |
73| Hardcoding color values like `text-blue-500` on icons | Use semantic colors like `text-primary` so icons inherit theme changes |
74| Choosing icons by visual appeal rather than semantic meaning | Map the concept first using the semantic mapping reference, then select the icon |
75| Missing `aria-label` on icon-only buttons | Add `aria-label="Description"` to buttons containing only icons |
76| Using old Heroicons import paths without size prefix | Use `@heroicons/react/24/outline` with the size prefix |
77
78## Delegation
79
80- **Audit existing icon usage for consistency and tree-shaking issues**: Use `Explore` agent to scan imports and identify mixed styles or wildcard imports
81- **Migrate icons from Font Awesome or Material to modern libraries**: Use `Task` agent with the migration guide reference
82- **Plan icon system architecture for a design system**: Use `Plan` agent to select library, define sizing conventions, and establish semantic mappings
83
84## References
85
86- [semantic-mapping.md](references/semantic-mapping.md) -- Full concept-to-icon tables by category (quality, price, location, trade-specific, navigation, status)
87- [icon-templates.md](references/icon-templates.md) -- React/HTML patterns with Tailwind (feature cards, buttons, inputs, navigation, status badges)
88- [library-comparison.md](references/library-comparison.md) -- Lucide vs Heroicons vs Phosphor (features, bundle size, import patterns)
89- [migration-guide.md](references/migration-guide.md) -- Font Awesome, Material Icons, Feather, and emoji to modern equivalents
90- [accessibility.md](references/accessibility.md) -- Decorative vs meaningful icons, aria attributes, screen reader patterns