Icon Design & Selection (Desktop)
The hard rule
Never use Lucide icons. Not as a placeholder, not "just for now," not for one-off icons. Lucide (and by extension the identical Feather-icon-derived look) is the single most recognizable visual tell of an AI-assisted or shadcn-template app — trained eyes clock it instantly, and it undercuts everything else this skill family does. If Lucide is already in the codebase, treat every instance of it as a bug to fix, not a default to build on top of.
This rule is absolute regardless of how the request is framed — "just use lucide for now," "it's fine for an MVP," or "everyone uses it" are not exceptions.
What to use instead
In order of preference:
- A small custom-drawn icon set matching the app's own brand geometry (e.g. if the brand motif is organic/rounded, draw icons with rounded joins and soft terminals; if it's geometric, draw them sharp). This is the strongest option for a product that wants to look intentional rather than assembled, and it's worth the time investment for a flagship app.
- A single well-chosen library, used consistently and modified to fit — Phosphor Icons, Tabler Icons, Iconoir, or Remix Icon are all solid, less-overexposed alternatives to Lucide. Pick exactly one. Set a consistent stroke width across the whole app (don't mix a 1.5px-stroke icon next to a 2px-stroke icon). Adjust the corner radius of the library's icons if needed to match the app's own radius scale from foundations.
- Never mix icon families. One icon from library A next to one from library B is worse than using an imperfect single library consistently — mismatched stroke weight, corner style, and optical size is immediately visible even to someone who couldn't name why it looks wrong.
Whichever route is chosen, lock it in a single place (a component/import wrapper, a theme resource, a sprite sheet) so nobody can casually reach for a different set six months later.
Selection logic — does this even need an icon?
Not every action needs an icon. Icons should:
- Represent something with a stable, widely-understood visual metaphor (trash = delete, gear = settings, magnifying glass = search). If the metaphor takes explanation, it's the wrong icon — or the action needs a text label instead.
- Be paired with a text label whenever the meaning isn't universal, or whenever the control is a primary/frequent action (icon-only is for toolbars and dense UI, not for a settings page's main actions).
- Never be invented purely to "fill visual space" next to a label — an icon that adds no information is decoration, and decoration without meaning is an anti-slop violation from
desktop-ui-foundations.
Consistency rules
- One optical size per context. Toolbar icons should all render at the same apparent size even if their underlying viewboxes differ slightly — normalize this, don't eyeball it.
- One stroke weight app-wide, or one fill style if using filled icons — never mix stroke and filled icons in the same view unless the fill is deliberately reserved for an "active/selected" state (see the color-system skill for state-driven icon treatment).
- Grid-align the artwork. Icons drawn or exported off a consistent pixel grid (typically 24×24 for a 16–20px rendered icon) will look crisper and align better with text baselines than ones scaled arbitrarily.
- Avoid decorative gradient fills on icons. A gradient-filled icon is a fast way to read as generic-AI polish; solid color communicates state (active/inactive/error) more clearly anyway.
Sizing tokens
Match to the button sizing scale in desktop-ui-buttons-controls:
12–14px — inline with caption/label text
16px — the default for most UI icons (menu items, list rows, inline buttons)
20px — toolbar and header icons
24px+ — reserved for empty-state or feature-highlight icons, used sparingly
App icon / tray icon / installer icon
The app's own icon (dock/taskbar/tray) is not a UI icon — it's a small piece of brand identity and deserves its own attention, not a reused UI glyph blown up large. It should:
- Read clearly at the smallest size it'll actually appear (16×16 tray icon), not just at the large marketing size.
- Follow each platform's shape conventions (macOS's rounded-square-with-inset-artwork convention vs. Windows' more literal square) rather than shipping one flat asset everywhere.
- Tie visually to the in-app brand motif rather than being an unrelated generic mark.
See desktop-installer-design for how this same icon shows up through the install flow.
Accessibility & internationalization
- Icon-only controls (toolbar buttons, close/collapse glyphs) need an accessible name exposed to the platform's accessibility API, not just a visual tooltip — tooltips are invisible to screen readers and to anyone who never hovers. See
desktop-ui-accessibility-i18n.
- Directional icons (back/forward, next/previous chevrons) should mirror in right-to-left layouts. Icons with no inherent direction (checkmark, play, star, trash) should not be flipped.
Review format
| Before |
After |
Why |
| Lucide icons used "just for the MVP" |
A single deliberately-chosen set (or custom-drawn set), used consistently |
Lucide is the single most recognizable AI-assisted-app tell; there's no version of "temporary" that avoids that read |
| Icon-only delete button with only a tooltip |
Same button plus an accessible name on the control itself |
Tooltips don't reach screen reader or touch-only users |
| Mixed 1.5px and 2px stroke icons in the same toolbar |
One stroke weight, normalized across the whole icon set |
Mismatched stroke weight is visible even to someone who can't name why it looks off |
1---2name: desktop-ui-icons3description: Use whenever choosing, drawing, sourcing, or reviewing icons in a desktop app — toolbar icons, sidebar icons, empty-state illustrations, tray/menu-bar icons, app icons. Enforces a hard rule against Lucide (and unmodified default icon sets generally) and gives a concrete selection and consistency process instead. Depends on desktop-ui-foundations. Trigger on "pick an icon," "icon set," "this icon looks wrong/mismatched," or "no lucide."4---56# Icon Design & Selection (Desktop)78## The hard rule910**Never use Lucide icons.** Not as a placeholder, not "just for now," not for one-off icons. Lucide (and by extension the identical Feather-icon-derived look) is the single most recognizable visual tell of an AI-assisted or shadcn-template app — trained eyes clock it instantly, and it undercuts everything else this skill family does. If Lucide is already in the codebase, treat every instance of it as a bug to fix, not a default to build on top of.1112This rule is absolute regardless of how the request is framed — "just use lucide for now," "it's fine for an MVP," or "everyone uses it" are not exceptions.1314## What to use instead1516In order of preference:17181. **A small custom-drawn icon set** matching the app's own brand geometry (e.g. if the brand motif is organic/rounded, draw icons with rounded joins and soft terminals; if it's geometric, draw them sharp). This is the strongest option for a product that wants to look intentional rather than assembled, and it's worth the time investment for a flagship app.192. **A single well-chosen library, used consistently and modified to fit** — Phosphor Icons, Tabler Icons, Iconoir, or Remix Icon are all solid, less-overexposed alternatives to Lucide. Pick exactly one. Set a consistent stroke width across the whole app (don't mix a 1.5px-stroke icon next to a 2px-stroke icon). Adjust the corner radius of the library's icons if needed to match the app's own radius scale from foundations.203. **Never mix icon families.** One icon from library A next to one from library B is worse than using an imperfect single library consistently — mismatched stroke weight, corner style, and optical size is immediately visible even to someone who couldn't name why it looks wrong.2122Whichever route is chosen, lock it in a single place (a component/import wrapper, a theme resource, a sprite sheet) so nobody can casually reach for a different set six months later.2324## Selection logic — does this even need an icon?2526Not every action needs an icon. Icons should:2728- Represent something with a **stable, widely-understood visual metaphor** (trash = delete, gear = settings, magnifying glass = search). If the metaphor takes explanation, it's the wrong icon — or the action needs a text label instead.29- Be paired with a text label whenever the meaning isn't universal, or whenever the control is a primary/frequent action (icon-only is for toolbars and dense UI, not for a settings page's main actions).30- Never be invented purely to "fill visual space" next to a label — an icon that adds no information is decoration, and decoration without meaning is an anti-slop violation from `desktop-ui-foundations`.3132## Consistency rules3334- **One optical size per context.** Toolbar icons should all render at the same apparent size even if their underlying viewboxes differ slightly — normalize this, don't eyeball it.35- **One stroke weight app-wide**, or one fill style if using filled icons — never mix stroke and filled icons in the same view unless the fill is deliberately reserved for an "active/selected" state (see the color-system skill for state-driven icon treatment).36- **Grid-align the artwork.** Icons drawn or exported off a consistent pixel grid (typically 24×24 for a 16–20px rendered icon) will look crisper and align better with text baselines than ones scaled arbitrarily.37- **Avoid decorative gradient fills on icons.** A gradient-filled icon is a fast way to read as generic-AI polish; solid color communicates state (active/inactive/error) more clearly anyway.3839## Sizing tokens4041Match to the button sizing scale in `desktop-ui-buttons-controls`:4243- `12–14px` — inline with caption/label text44- `16px` — the default for most UI icons (menu items, list rows, inline buttons)45- `20px` — toolbar and header icons46- `24px+` — reserved for empty-state or feature-highlight icons, used sparingly4748## App icon / tray icon / installer icon4950The app's own icon (dock/taskbar/tray) is not a UI icon — it's a small piece of brand identity and deserves its own attention, not a reused UI glyph blown up large. It should:5152- Read clearly at the smallest size it'll actually appear (16×16 tray icon), not just at the large marketing size.53- Follow each platform's shape conventions (macOS's rounded-square-with-inset-artwork convention vs. Windows' more literal square) rather than shipping one flat asset everywhere.54- Tie visually to the in-app brand motif rather than being an unrelated generic mark.5556See `desktop-installer-design` for how this same icon shows up through the install flow.5758## Accessibility & internationalization5960- Icon-only controls (toolbar buttons, close/collapse glyphs) need an accessible name exposed to the platform's accessibility API, not just a visual tooltip — tooltips are invisible to screen readers and to anyone who never hovers. See `desktop-ui-accessibility-i18n`.61- Directional icons (back/forward, next/previous chevrons) should mirror in right-to-left layouts. Icons with no inherent direction (checkmark, play, star, trash) should not be flipped.6263## Review format6465| Before | After | Why |66|---|---|---|67| Lucide icons used "just for the MVP" | A single deliberately-chosen set (or custom-drawn set), used consistently | Lucide is the single most recognizable AI-assisted-app tell; there's no version of "temporary" that avoids that read |68| Icon-only delete button with only a tooltip | Same button plus an accessible name on the control itself | Tooltips don't reach screen reader or touch-only users |69| Mixed 1.5px and 2px stroke icons in the same toolbar | One stroke weight, normalized across the whole icon set | Mismatched stroke weight is visible even to someone who can't name why it looks off |