SVG Icon Naming Conventions for Design Systems
How to name SVG icons consistently across Figma, code, and documentation — comparing Lucide, Tabler, and Material naming systems with a practical framework for your own design system.
Icon names are the invisible infrastructure of a design system. A well-named icon is findable in search, predictable in autocomplete, and self-documenting in code. A poorly named icon gets duplicated, misused, and quietly abandoned. Most naming problems don’t surface until you have 200+ icons and no one can remember if the “arrow-right” or “chevron-right” is the navigation icon.
This guide compares the naming strategies of three production systems, identifies their tradeoffs, and gives you a practical naming framework to apply immediately.
Why naming matters at scale
At 20 icons, names barely matter — you remember them all. At 200, you need a system. At 2,000, a bad system causes:
- Duplicate icons under different names (
arrow-forwardandarrow-right) - Wrong icon used because search returns multiple similar results
- Inconsistent imports (
SearchIconin one file,IconSearchin another) - Broken refactors when icons are renamed after the fact
These six icons all “point right” — without a consistent naming convention, teams end up using them interchangeably and inconsistently.
The three major naming systems
System 1: Lucide — verb-noun / noun (kebab-case)
Lucide uses lowercase kebab-case with a descriptive name. Action icons use a verb, object icons use a noun, and compound icons combine them:
search → noun
settings → noun (not "gear" or "cog")
arrow-right → noun + direction
file-text → compound noun
alert-triangle → noun + shape modifier
layout-dashboard → compound noun (context + component)
Strengths: Human-readable, matches plain English description, works well in search.
Weaknesses: No enforced prefix — Icon must be added in import statements. Some names are opinionated (settings vs gear).
System 2: Tabler — Icon prefix + PascalCase
Tabler appends Icon as a prefix to every exported component name:
IconSearch → Icon + Search
IconLayoutDashboard → Icon + compound descriptor
IconAlertTriangle → Icon + compound descriptor
IconArrowRight → Icon + compound descriptor
Strengths: Impossible to confuse icons with non-icon components in autocomplete. All icons surface together when you type Icon.
Weaknesses: Verbose. IconLayoutDashboard is long. The Icon prefix is redundant when your IDE already has type info.
System 3: Material Symbols — snake_case with _outline / _filled suffixes
Google’s Material Symbols uses snake_case names with optional suffixes for variants:
search
search_outlined
settings
notifications
notifications_outlined
notifications_active
Strengths: Maps directly to the CSS variable system used for variable fonts. Variant suffixes are consistent.
Weaknesses: Doesn’t work well as TypeScript identifiers (underscores aren’t conventional in React component names). The filled/outlined distinction requires renaming between variants.
A practical naming framework
For a new design system, this hybrid framework combines the best parts of each:
Rule 1: kebab-case file names, PascalCase component names
assets/icons/search.svg → SearchIcon (component)
assets/icons/arrow-right.svg → ArrowRightIcon (component)
assets/icons/file-text.svg → FileTextIcon (component)
The Icon suffix in the component name prevents collisions with non-icon components:
// Unambiguous — you know this is an SVG icon
import { SearchIcon, FileTextIcon } from '@/components/icons';
// Ambiguous — is SearchButton a button or an icon?
import { Search } from '@/components/icons';
SearchIcon, SettingsIcon, BellIcon — all surface in autocomplete when you type the noun (Search, Settings, Bell). With IconSearch prefix, you have to type Icon first, which is rarely how developers think of icons.
Rule 2: Noun-first, direction/modifier second
arrow-right ✅ (noun: arrow, modifier: direction)
right-arrow ❌ (modifier first — harder to group in sorted lists)
bell-dot ✅ (noun: bell, modifier: has-dot)
notification ❌ (semantic alias — different from visual name)
chart-bar ✅ (noun: chart, modifier: type)
bar-chart ❌ (inverts standard sort grouping)
Noun-first means all variants of an icon group together alphabetically:
arrow-down
arrow-left
arrow-right
arrow-up
arrow-up-circle
arrow-up-right
Rule 3: Visual names, not semantic names
Name the icon for what it looks like, not what it means in your product:
gear ✅ (visual: a gear shape)
settings ⚠️ (semantic: what the gear means in your product)
configuration ❌ (product-specific term)
Visual names are portable — they work in every product context. Semantic names lock the icon to one use case: a settings icon used for “preferences” feels wrong; a gear icon doesn’t.
Exception: Universally recognized semantic icons are fine: home, search, close, menu. These visual forms are so strongly associated with their meaning that the semantic name is the right choice.
Rule 4: Use a size/weight suffix for multi-variant libraries
heart-16 → 16px optimized variant
heart → default (24px)
heart-32 → 32px variant
heart → default weight
heart-bold → bold weight
heart-duotone → duotone variant
This makes variant selection clear without inspecting the component:
import { HeartIcon, HeartDuotoneIcon } from '@/components/icons';
Rule 5: Document semantic aliases separately
Rather than naming icons semantically, create a semantic alias layer:
// src/components/icons/semantic.ts
// Maps product concepts to visual icons
export { GearIcon as SettingsIcon } from './index';
export { BellIcon as NotificationsIcon } from './index';
export { PersonIcon as ProfileIcon } from './index';
export { LayoutDashboardIcon as DashboardIcon } from './index';
Developers can use semantic names in product code while the icon library remains visually named:
// Product code — uses semantic names
import { SettingsIcon, NotificationsIcon } from '@/components/icons/semantic';
// Icon library code — uses visual names
import { GearIcon, BellIcon } from '@/components/icons';
Naming for searchability
Icon search — both in design tools and code editors — relies on names. Test your naming system with these search queries:
| Developer thinks… | Should find… |
|---|---|
| “delete” | TrashIcon (needs alias: DeleteIcon = TrashIcon) |
| “close” | XIcon or CloseIcon |
| ”loading” | LoaderIcon or SpinnerIcon |
| ”warning” | AlertTriangleIcon |
| ”info” | InfoCircleIcon or InfoIcon |
| ”check” | CheckIcon |
| ”link” | LinkIcon or ExternalLinkIcon |
Build a search-alias map for common conceptual mismatches:
// src/components/icons/aliases.ts
export { TrashIcon as DeleteIcon } from './index';
export { XIcon as CloseIcon } from './index';
export { Loader2Icon as SpinnerIcon } from './index';
export { AlertTriangleIcon as WarningIcon } from './index';
Renaming an icon breaks every import in every component. When you discover a name mismatch (developers keep searching for “close” but the icon is named XIcon), add an alias rather than renaming. Aliases are additive; renames are destructive.
Documenting your icon vocabulary
A naming convention only works if it’s documented and enforced. The minimum documentation:
1. A naming guide (one page in your design system docs):
- The case format (kebab-case files, PascalCase components)
- Noun-first rule with examples
- The visual-name policy with exception list
- How to request a new icon
2. An icon inventory (searchable table of all icons):
- Visual name, semantic aliases, Figma component name, React import name
- Helps identify duplicates before they proliferate
3. Lint rules (optional but powerful):
// .eslintrc — custom rule: icons must have Icon suffix
'local-rules/icon-naming': ['error', { suffix: 'Icon' }]
Migrating a legacy naming system
If your codebase already has inconsistent icon names, migrate gradually:
- Add the
Iconsuffix as aliases first:export { Search as SearchIcon } - Update new code to use the new names
- Run a codemod to migrate existing usage:
jscodeshift --transform=icon-rename src/ - Remove the old aliases in a major version bump
Never do a big-bang rename — it creates a massive PR, breaks git blame, and introduces merge conflicts across every feature branch.
Related Reading
- How to Build a Custom SVG Icon Component Library in React and Next.js
- Figma to React Icon Pipeline: SVGO + SVGR Automation
- SVG Search Workflow for Teams
- Managing SVG Icon Updates Across a Monorepo
- Creating and Exporting an Icon Library in Figma: Best Practices
- How to Add Custom Icons to Lucide — The Complete 2026 Guide