Skip to content
Back to skills

Icon Audit

ASecurity

Audit and fix icon and illustration usage across the codebase — mixed libraries, wrong sizes, hardcoded colors, missing accessibility, flex compression, and illustration anti-patterns. Run before any design review.

  • 2 stars
  • 0 votes
  • 4 copies
  • 9 views
  • Added October 26, 2026
designgoreact

Works with

  • cli

Security analysis

A100/100

Scanned October 26, 2026

npx -y skills add JoshuaShepherd/my-skills --skill icon-audit --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Icon Audit?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Icon Audit
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/joshuashepherd-icon-audit-f79dd64a/badge)](https://www.skillsdirectory.com/skills/joshuashepherd-icon-audit-f79dd64a)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: icon-audit
description: Audit and fix icon and illustration usage across the codebase — mixed libraries, wrong sizes, hardcoded colors, missing accessibility, flex compression, and illustration anti-patterns. Run before any design review.
user-invocable: true
allowed-tools: Read, Grep, Glob, Edit
---

Audit and fix icon and illustration anti-patterns across the codebase.

Target: $ARGUMENTS

If no target is provided, scan `src/components/` and `src/app/(public)/`.

## Before Starting

1. Read `src/app/globals.css` to confirm the current semantic color token inventory.
2. Read `src/components/ui/icon.tsx` if it exists — this is the canonical Icon wrapper. If it doesn't exist, note it as a critical gap.
3. Check which icon libraries are installed: `grep -r "from 'lucide-react'\|from '@heroicons\|from 'react-icons\|from 'phosphor" package.json`

## Scan Checklist

### 1. MIXED ICON LIBRARIES (Critical)

This codebase uses **Lucide React only**. Any other icon library is a violation.

Search for:
- `from '@heroicons/react'`
- `from 'react-icons'`
- `from 'phosphor-react'`
- `from '@radix-ui/react-icons'` — allowed ONLY inside `src/components/ui/*` (shadcn internals)
- `from 'feather-icons'`
- Any `<svg>` with inline path data that duplicates a Lucide icon

**Fix:** Replace with the equivalent Lucide icon. Map using the Lucide icon search at lucide.dev.

### 2. RAW LUCIDE USAGE (High)

Icons should always be used via the canonical `<Icon>` wrapper (`src/components/ui/icon.tsx`), not imported and rendered directly. Raw usage bypasses the size scale, accessibility defaults, and flex-compression guard.

Search for patterns like:
```
import { ArrowRight, Check, X } from 'lucide-react'
// then used as: <ArrowRight className="w-4 h-4" />
```

**Allowed exception:** Inside `src/components/ui/*` (shadcn primitives) and the Icon wrapper itself.

**Fix:** Replace `<IconName className="w-N h-N" />` with `<Icon icon={IconName} size="sm" />`.

### 3. ARBITRARY ICON SIZES (High)

Icons must use the canonical size token scale, not arbitrary pixel values:

| Token | Size | Use case |
|-------|------|----------|
| `xs`  | 12px | Captions, badges, inline metadata |
| `sm`  | 16px | Inline text, form labels, table cells |
| `md`  | 20px | Default UI, buttons, nav items |
| `lg`  | 24px | Section headers, card actions, prominent UI |
| `xl`  | 32px | Empty states, feature highlights |
| `2xl` | 48px | Hero sections, marketing, onboarding |

Search for:
- `w-[` or `h-[` with pixel values applied to icon elements
- `w-3 h-3`, `w-5 h-5`, `w-6 h-6`, `w-7 h-7`, `w-8 h-8`, `w-10 h-10` — these bypass the token scale
- `size={` with numeric values other than 12, 16, 20, 24, 32, 48

**Fix:** Replace with the `<Icon size="md">` pattern.

### 4. HARDCODED ICON COLORS (High)

Icons must inherit their color from the surrounding text context via `currentColor`. Never set a specific color on an icon.

Search for:
- `text-blue-*`, `text-gray-*`, `text-red-*` etc. on icon elements (should be semantic: `text-muted-foreground`, `text-primary`, `text-destructive`)
- `fill="` or `stroke="` with hex values or named colors (not `currentColor`) in inline SVGs
- `color=` prop on Lucide icons

**Fix:** Remove the color class from the icon; apply it to the parent container using semantic tokens instead. Or, if only the icon needs color, use `text-primary`, `text-muted-foreground`, `text-destructive`.

### 5. MISSING FLEX-COMPRESSION GUARD (Medium)

Icons inside flex or grid containers will compress if `shrink-0` is missing.

Search for icon elements (or `<Icon>` wrapper usages) inside:
- `flex` containers without `shrink-0` on the icon
- `items-center` rows where the icon is a sibling of text

**Fix:** Add `shrink-0` to the icon's className (the `<Icon>` wrapper applies this automatically when used correctly).

### 6. ACCESSIBILITY VIOLATIONS (High)

**Pattern 1 — Decorative icons (no meaning without adjacent text):**
```tsx
// ✅ Correct
<Icon icon={Check} size="md" aria-hidden />
<span>Saved</span>

// ❌ Wrong — icon has no label, no aria-hidden
<CheckIcon className="w-5 h-5" />
<span>Saved</span>
```

**Pattern 2 — Icon-only buttons (icon IS the only affordance):**
```tsx
// ✅ Correct
<Button variant="ghost" size="icon" aria-label="Close dialog">
  <Icon icon={X} size="md" aria-hidden />
</Button>

// ❌ Wrong — no label, screen reader reads nothing useful
<button onClick={onClose}>
  <XIcon className="w-5 h-5" />
</button>
```

**Pattern 3 — Standalone meaningful icons (rare — chart markers, status indicators):**
```tsx
// ✅ Correct
<Icon icon={AlertTriangle} size="md" label="Warning" />

// Or for SVG illustrations:
<svg role="img" aria-label="Empty inbox illustration">
  <title>Empty inbox illustration</title>
  ...
</svg>
```

Search for:
- Icon-only `<button>` elements without `aria-label`
- `<Button size="icon">` without `aria-label`
- Icon elements that are the sole content of a clickable element, with no accessible label

### 7. ILLUSTRATION ANTI-PATTERNS (Medium)

Illustrations are larger SVGs used for empty states, onboarding, marketing sections, and feature highlights. They follow different rules from icons.

Search for:
- `<img src="*.png">` or `<img src="*.jpg">` used for illustrations (should be SVG)
- Inline SVG without `role="img"` and `<title>` (if it conveys meaning)
- SVG files that embed hardcoded hex colors (should use CSS custom properties to inherit theme)
- Illustrations that don't have a dark-mode variant or don't use `currentColor`/CSS vars
- `<img>` elements with empty or missing `alt` attribute
- Raster PNGs in `public/images/illustrations/` that could be SVG

**Fix per case:**
- Replace PNG illustrations with SVG equivalents
- Add `role="img"` + `<title>` to meaningful inline SVGs
- For decorative illustrations: `aria-hidden="true"` or `alt=""`
- Refactor hardcoded SVG colors to use `currentColor` or CSS custom properties

### 8. STROKE WEIGHT CONSISTENCY (Low)

Lucide icons default to `strokeWidth={2}`. At `xl` / `2xl` sizes used in marketing sections, `strokeWidth={1.5}` looks more refined. Never mix 1.5 and 2 in the same UI region.

Search for `strokeWidth=` props on icons and verify they follow the pattern:
- `xs`–`lg` sizes: `strokeWidth={2}` (default, can omit)
- `xl`–`2xl` sizes: `strokeWidth={1.5}` preferred

## Fixing Protocol

1. **Read each file first** before editing.
2. **Fix critical issues first** (mixed libraries, a11y), then high, then medium, then low.
3. **Never modify `src/components/ui/*`** (shadcn internals).
4. **Batch edits per file** — fix all issues in a file in one edit.
5. **If `<Icon>` wrapper doesn't exist**, note it for icon-system to create — don't create it inline here.

## Output Format

```
## Icon & Illustration Audit Report

### Summary
- Files scanned: X
- Violations found: X (Critical: X, High: X, Medium: X, Low: X)
- Auto-fixed: X
- Manual review needed: X

### Critical: Icon Wrapper Missing
[ ] src/components/ui/icon.tsx does not exist → Run /icon-system to create it

### Violations by Category

#### 1. MIXED LIBRARIES — X violations
| File | Line | Violation | Fix |
|------|------|-----------|-----|

#### 2. RAW LUCIDE USAGE — X violations
| File | Line | Violation | Fix |
|------|------|-----------|-----|

#### 3. ARBITRARY SIZES — X violations
...

#### 4. HARDCODED COLORS — X violations
...

#### 5. FLEX COMPRESSION — X violations
...

#### 6. ACCESSIBILITY — X violations
...

#### 7. ILLUSTRATIONS — X violations
...

#### 8. STROKE WEIGHT — X violations
...

### Files Modified
- path/to/file.tsx — X fixes applied

### Remaining Manual Work
- Items that require design decisions or new assets
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.