Skip to main content
Technology & EngineeringDesign Tool Services182 lines

Iconify

Integrate icons at scale with the Iconify framework. Use framework-specific

Quick Summary27 lines
You are an expert in Iconify, the universal icon framework that provides access to 200k+ icons from 100+ open-source sets through a single API. You configure tree-shakeable React/Vue components, build custom icon sets, and optimize icon delivery for production.

## Key Points

- **Bundling entire icon sets** -- `@iconify/json` is 60MB+; import only the specific icons you need or use `addIcon` for subsets.
- **Using inline SVG strings instead of the component** -- loses Iconify's caching, deduplication, and consistent sizing.
- **Ignoring accessibility** -- always pair decorative icons with `aria-hidden="true"` and meaningful icons with `aria-label`.
- **Mixing icon fonts and Iconify** -- font icons have different alignment and sizing behavior; stick to one system per project.
- Accessing icons from multiple icon sets without installing separate packages for each.
- Building a design system icon layer that supports custom SVGs alongside open-source sets.
- Delivering icons on-demand to reduce initial bundle size on large applications.
- Creating a self-hosted icon API for enterprise or air-gapped environments.
- Generating icon sprites or static SVG bundles as part of a build pipeline.

## Quick Example

```typescript
// First paint blocked until API responds -- bad for LCP
<Icon icon="mdi:menu" />  // fetches from api.iconify.design at runtime
```

```typescript
// Icon inherits text color automatically
<Icon icon="lucide:check" className="text-green-600" />
```
skilldb get design-tool-services-skills/IconifyFull skill: 182 lines
Paste into your CLAUDE.md or agent config

Iconify Icon Framework

You are an expert in Iconify, the universal icon framework that provides access to 200k+ icons from 100+ open-source sets through a single API. You configure tree-shakeable React/Vue components, build custom icon sets, and optimize icon delivery for production.

Core Philosophy

One API, Every Icon Set

Instead of installing separate packages for Material Icons, Lucide, Heroicons, and Phosphor, Iconify provides a unified interface. Reference any icon by its prefix:name identifier.

Bundle What You Use

Iconify supports two loading strategies: on-demand via the API (zero bundle cost, requires network) and offline bundles (tree-shaken, no runtime requests). Choose per use case.

SVG-Native, Not Font-Based

Iconify renders real SVG elements, not font glyphs. This means icons scale crisply, support currentColor, and are accessible with proper ARIA attributes.

Setup

# Framework-specific packages
npm install @iconify/react        # React
npm install @iconify/vue           # Vue 3
npm install @iconify-icon/react    # Web Component wrapper for React

# Offline bundle tooling
npm install -D @iconify/tools @iconify/utils @iconify/json
// Basic React usage -- loads icon on-demand from Iconify API
import { Icon } from "@iconify/react";

export function App() {
  return <Icon icon="mdi:home" width={24} />;
}

Key Patterns

Do: Use offline bundles for critical UI icons

import { addCollection } from "@iconify/react";
import icons from "@iconify-icons/lucide"; // tree-shakeable

// Or manually register a subset
addCollection({
  prefix: "app",
  icons: {
    home: { body: '<path d="M3 12l9-9 9 9"/><path d="M9 21V9h6v12"/>' },
    settings: { body: '<circle cx="12" cy="12" r="3"/>' },
  },
  width: 24,
  height: 24,
});

Not: Rely solely on the API for above-the-fold icons

// First paint blocked until API responds -- bad for LCP
<Icon icon="mdi:menu" />  // fetches from api.iconify.design at runtime

Do: Use currentColor for theme-adaptive icons

// Icon inherits text color automatically
<Icon icon="lucide:check" className="text-green-600" />

Common Patterns

Create a custom icon set from SVG files

// scripts/build-icons.ts
import { importDirectory, cleanupSVG, runSVGO } from "@iconify/tools";
import { writeFileSync } from "node:fs";

async function buildIconSet() {
  const iconSet = await importDirectory("src/assets/icons", { prefix: "app" });

  await iconSet.forEach(async (name, type) => {
    if (type !== "icon") return;
    const svg = iconSet.toSVG(name)!;
    cleanupSVG(svg);
    runSVGO(svg);
    iconSet.fromSVG(name, svg);
  });

  const exported = iconSet.export();
  writeFileSync("src/icons/app-icons.json", JSON.stringify(exported, null, 2));
}
buildIconSet();

Type-safe icon component wrapper

import { Icon, type IconProps } from "@iconify/react";

// Restrict to known icon names for type safety
type AppIcon =
  | "app:home"
  | "app:settings"
  | "lucide:search"
  | "lucide:x";

interface TypedIconProps extends Omit<IconProps, "icon"> {
  icon: AppIcon;
}

export function AppIcon({ icon, ...props }: TypedIconProps) {
  return <Icon icon={icon} width={props.width ?? 20} {...props} />;
}

Vue 3 composition with Iconify

<script setup lang="ts">
import { Icon } from "@iconify/vue";

defineProps<{ iconName: string; size?: number }>();
</script>

<template>
  <Icon :icon="iconName" :width="size ?? 20" :height="size ?? 20" />
</template>

Self-hosted Iconify API

// For air-gapped or low-latency environments
import { createServer } from "node:http";
import { lookupCollections, locate } from "@iconify/json";
import { getIconData, iconToSVG, iconToHTML } from "@iconify/utils";

async function serveSvg(prefix: string, name: string): Promise<string | null> {
  const collection = JSON.parse(
    (await import(`@iconify/json/json/${prefix}.json`, { assert: { type: "json" } }))
      .default
  );
  const data = getIconData(collection, name);
  if (!data) return null;
  const rendered = iconToSVG(data, { height: "auto" });
  return iconToHTML(rendered.body, rendered.attributes);
}

Preload strategy for dynamic icon usage

import { loadIcons } from "@iconify/react";

// Preload icons you know you'll need (e.g., on route change)
function preloadDashboardIcons() {
  loadIcons(
    ["mdi:chart-bar", "mdi:account-group", "mdi:bell-outline"],
    (loaded, missing) => {
      if (missing.length) console.warn("Icons not found:", missing);
    }
  );
}

Anti-Patterns

  • Bundling entire icon sets -- @iconify/json is 60MB+; import only the specific icons you need or use addIcon for subsets.
  • Using inline SVG strings instead of the component -- loses Iconify's caching, deduplication, and consistent sizing.
  • Ignoring accessibility -- always pair decorative icons with aria-hidden="true" and meaningful icons with aria-label.
  • Mixing icon fonts and Iconify -- font icons have different alignment and sizing behavior; stick to one system per project.

When to Use

  • Accessing icons from multiple icon sets without installing separate packages for each.
  • Building a design system icon layer that supports custom SVGs alongside open-source sets.
  • Delivering icons on-demand to reduce initial bundle size on large applications.
  • Creating a self-hosted icon API for enterprise or air-gapped environments.
  • Generating icon sprites or static SVG bundles as part of a build pipeline.

Install this skill directly: skilldb add design-tool-services-skills

Get CLI access →