Contributing Icons
How to add new icons to the @loke/icons library.
Contributing Icons
The @loke/icons library contains 107 carefully crafted icons. New icons are generated from SVG source files using a build script. This guide walks you through the process of adding icons to the library.
Icons are auto-generated from SVG sources. Always run bun run gen after adding or updating SVGs.
Step 1: Add your SVG
Location: packages/icons/src/meta/
Naming convention: Use PascalCase for SVG filenames (matching React component conventions).
Examples:
SearchIcon.svgChevronUp.svgMailAlert.svg
SVG requirements:
- Include a
viewBoxattribute (e.g.,viewBox="0 0 24 24") - Prefer stroke-based designs for consistency with the icon library style
- Keep dimensions square (24×24 is standard)
- Simplify paths when possible
Example SVG structure:
<svg
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<circle cx="11" cy="11" r="8" />
<path d="m21 21-4.35-4.35" />
</svg>Step 2: Add metadata (optional)
Metadata helps organize, tag, and alias icons for search and filtering. Create a JSON file with the same base name as your SVG.
Location: packages/icons/src/meta/<icon-name>.json
Schema:
{
"tags": ["keyword1", "keyword2", "keyword3"],
"categories": ["ui", "navigation", "commerce"],
"aliases": [
{
"name": "AlternativeName"
},
{
"name": "OldName",
"deprecated": true,
"deprecationReason": "Use SearchIcon instead",
"toBeRemovedInVersion": "2.0.0"
}
]
}Fields:
| Field | Type | Description |
|---|---|---|
tags | string[] | Keywords for searching/filtering (e.g., "search", "find", "magnifying-glass") |
categories | string[] | Icon categories for organization (see available categories below) |
aliases | object[] | Alternative import names (optional, useful for backward compatibility) |
Available categories:
ui— General UI elements (menu, checkbox, button, etc.)navigation— Navigation-related (arrows, chevrons, etc.)commerce— Commerce-related (cart, payment, discount, etc.)notifications— Alerts, bells, messagesmedia— Images, video, play, pausearrows— Directional arrowssocial— Social mediafinance— Money, currency, dollar signstime— Clock, calendar, scheduleuser— User profiles, people- And 27 more...
Example metadata file:
{
"tags": ["search", "find", "magnifying glass", "lookup"],
"categories": ["ui", "navigation"],
"aliases": [
{
"name": "SearchIcon"
},
{
"name": "Magnifier",
"deprecated": true,
"deprecationReason": "Use Search instead",
"toBeRemovedInVersion": "1.5.0"
}
]
}Step 3: Generate icons
After adding SVG and metadata files, run the generation script:
cd packages/icons
bun run genThis script will:
- Parse all SVG files in
src/meta/ - Convert SVG paths to React component format
- Generate TypeScript components in
src/icons/(kebab-case filenames) - Create or update metadata JSON files if missing
- Regenerate
src/loke-icons.ts(exports all icons) - Regenerate
src/aliases.ts(exports aliases) - Regenerate
src/index.ts(main entry point) - Format all files with Biome
Step 4: Build and verify
Compile the package for distribution:
cd packages/icons
bun run buildThis generates the dist/ folder with compiled JavaScript and TypeScript declarations.
Verify the icon appears in documentation and can be imported:
import { Search } from '@loke/icons';
function App() {
return <Search size={24} />;
}Step 5: Commit
Commit all generated and source files together:
git add packages/icons/src/meta/*.svg
git add packages/icons/src/meta/*.json
git add packages/icons/src/icons/
git add packages/icons/src/loke-icons.ts
git add packages/icons/src/aliases.ts
git add packages/icons/src/index.ts
git commit -m "feat(icons): add Search icon"Always commit the generated files alongside source SVGs. The generated components are part of the published package.
Icon metadata schema (detailed)
Tags
Keywords that describe the icon. Use common synonyms:
{
"tags": [
"search",
"find",
"magnifying glass",
"lookup",
"query",
"filter"
]
}Categories
Assign icons to one or more of 37 categories for organization:
{
"categories": ["ui", "navigation"]
}Aliases
Define alternative names for the icon (useful for backward compatibility or multiple naming conventions):
{
"aliases": [
{
"name": "SearchIcon"
},
{
"name": "Magnifier",
"deprecated": true,
"deprecationReason": "Use Search instead",
"toBeRemovedInVersion": "2.0.0"
}
]
}Alias properties:
| Property | Type | Description |
|---|---|---|
name | string | Alternative import name |
deprecated | boolean | Mark as deprecated (optional) |
deprecationReason | string | Reason for deprecation (optional) |
toBeRemovedInVersion | string | Version when alias will be removed (optional) |
Workflow example
-
Add SVG:
packages/icons/src/meta/NotificationBell.svg -
Add metadata:
packages/icons/src/meta/notification-bell.json { "tags": ["alert", "notification", "bell", "sound"], "categories": ["notifications", "ui"], "aliases": [ { "name": "BellAlert" } ] } -
Generate:
cd packages/icons && bun run gen -
Build:
bun run build -
Verify:
import { NotificationBell, BellAlert } from '@loke/icons'; <NotificationBell size={24} /> -
Commit:
git add packages/icons/ git commit -m "feat(icons): add NotificationBell icon"
Best practices
- Consistent style: Match the stroke width, roundness, and visual weight of existing icons
- Descriptive names: Use clear, descriptive names that indicate what the icon represents
- Good tags: Add 3-5 relevant keywords for discoverability
- Test imports: Verify the icon can be imported after generation
- SVG optimization: Keep SVG files clean and minimal; complex shapes should be simplified
- Aliases for variants: If you have multiple similar icons, use aliases to provide alternative names
Troubleshooting
Icon isn't appearing after gen:
- Verify the SVG filename uses PascalCase
- Check that
src/meta/contains the SVG file - Run
bun run genagain - Check for build errors in the console
Import path is wrong:
- The generated component name is kebab-case version of the filename
- Example:
SearchIcon.svg→import { SearchIcon } from '@loke/icons'
Metadata not generated:
- Metadata JSON files are optional; if missing,
gencreates a basic one - You can manually edit metadata after generation
Build fails:
- Run
bun run lintto check for syntax errors - Verify SVG is valid XML
- Check that all SVGs have
viewBoxattributes
Resources
- Icon library: @loke/icons on npm
- Source code:
packages/icons/in the monorepo - Build script:
packages/icons/gen.ts - Documentation:
packages/icons/README.md