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.svg
  • ChevronUp.svg
  • MailAlert.svg

SVG requirements:

  • Include a viewBox attribute (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:

FieldTypeDescription
tagsstring[]Keywords for searching/filtering (e.g., "search", "find", "magnifying-glass")
categoriesstring[]Icon categories for organization (see available categories below)
aliasesobject[]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, messages
  • media — Images, video, play, pause
  • arrows — Directional arrows
  • social — Social media
  • finance — Money, currency, dollar signs
  • time — Clock, calendar, schedule
  • user — 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 gen

This script will:

  1. Parse all SVG files in src/meta/
  2. Convert SVG paths to React component format
  3. Generate TypeScript components in src/icons/ (kebab-case filenames)
  4. Create or update metadata JSON files if missing
  5. Regenerate src/loke-icons.ts (exports all icons)
  6. Regenerate src/aliases.ts (exports aliases)
  7. Regenerate src/index.ts (main entry point)
  8. Format all files with Biome

Step 4: Build and verify

Compile the package for distribution:

cd packages/icons
bun run build

This 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:

PropertyTypeDescription
namestringAlternative import name
deprecatedbooleanMark as deprecated (optional)
deprecationReasonstringReason for deprecation (optional)
toBeRemovedInVersionstringVersion when alias will be removed (optional)

Workflow example

  1. Add SVG:

    packages/icons/src/meta/NotificationBell.svg
  2. Add metadata:

    packages/icons/src/meta/notification-bell.json
    {
      "tags": ["alert", "notification", "bell", "sound"],
      "categories": ["notifications", "ui"],
      "aliases": [
        { "name": "BellAlert" }
      ]
    }
  3. Generate:

    cd packages/icons && bun run gen
  4. Build:

    bun run build
  5. Verify:

    import { NotificationBell, BellAlert } from '@loke/icons';
    <NotificationBell size={24} />
  6. 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 gen again
  • Check for build errors in the console

Import path is wrong:

  • The generated component name is kebab-case version of the filename
  • Example: SearchIcon.svgimport { SearchIcon } from '@loke/icons'

Metadata not generated:

  • Metadata JSON files are optional; if missing, gen creates a basic one
  • You can manually edit metadata after generation

Build fails:

  • Run bun run lint to check for syntax errors
  • Verify SVG is valid XML
  • Check that all SVGs have viewBox attributes

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