ExIconify

View Source

Hex.pm Docs License

Iconify icons for Elixir and Phoenix applications.

Access 200,000+ icons from 100+ icon sets including Lucide, Material Design Icons, Tabler, Phosphor, Heroicons, and more.

Features

  • 🎨 100+ icon sets - Lucide, MDI, Tabler, Phosphor, Heroicons, and more
  • Fast caching - Icons are cached in ETS for instant access
  • 🔌 Phoenix integration - Ready-to-use <.icon> component
  • 🎯 Simple API - Just ExIconify.get!("lucide:home")
  • 📦 Zero config - Works out of the box
  • 🌐 Always up-to-date - Fetches from Iconify API

Installation

Add ex_iconify to your list of dependencies in mix.exs:

def deps do
  [
    {:ex_iconify, "~> 0.1.0"},
    {:req, "~> 0.5"}  # Optional but recommended
  ]
end

Quick Start

Basic Usage

# Get an icon SVG
{:ok, svg} = ExIconify.get("lucide:home")

# Get icon (returns fallback on error)
svg = ExIconify.get!("lucide:home")

# Check if icon exists
ExIconify.exists?("lucide:home")

Phoenix / LiveView

Import the component in your web module:

# lib/my_app_web.ex
defp html_helpers do
  quote do
    # ... other imports
    import ExIconify.Icon
  end
end

Use in your templates:

<%!-- Basic usage --%>
<.icon name="lucide:home" />

<%!-- With custom size and color --%>
<.icon name="lucide:heart" class="size-6 text-red-500" />

<%!-- Different icon sets --%>
<.icon name="mdi:account" />
<.icon name="tabler:star" />
<.icon name="ph:house-bold" />

<%!-- Animated spinner --%>
<.icon name="lucide:loader-2" class="size-5 animate-spin" />

Icon Format

Icons use the format set:icon-name:

SetPrefixExample
Lucidelucidelucide:home
Material Designmdimdi:account
Tablertablertabler:star
Phosphorphph:house
Heroiconsheroiconsheroicons:home
Remixriri:home-line
Carboncarboncarbon:home

Browse all icons at: icon-sets.iconify.design

Components

<.icon>

Basic icon component:

<.icon name="lucide:home" />
<.icon name="lucide:heart" class="size-6 text-red-500" />

<.icon_with_label>

Icon with text label:

<.icon_with_label name="lucide:home" label="Home" />
<.icon_with_label name="lucide:settings" label="Settings" icon_class="size-5" />

<.icon_button>

Accessible icon button:

<.icon_button name="lucide:plus" label="Add item" />
<.icon_button name="lucide:trash" label="Delete" class="text-red-500" />

Icon link:

<.icon_link name="lucide:external-link" label="Open docs" href="https://docs.example.com" />

Configuration

Configure in config/config.exs:

config :ex_iconify,
  # Custom API endpoint (default: https://api.iconify.design)
  api_url: "https://api.iconify.design",
  
  # Request timeout in milliseconds (default: 5000)
  api_timeout: 5_000,
  
  # Cache TTL (default: 24 hours)
  cache_ttl: :timer.hours(24)

Preloading Icons

For faster initial loads, preload commonly used icons at startup:

# In your application.ex
def start(_type, _args) do
  children = [
    # ... other children
  ]

  # Preload icons after supervision tree starts
  Task.start(fn ->
    ExIconify.preload([
      "lucide:home",
      "lucide:user",
      "lucide:settings",
      "lucide:search"
    ])
  end)

  Supervisor.start_link(children, opts)
end

Icon Sets

Get information about popular icon sets:

# List popular sets
ExIconify.Sets.popular()

# Get sample icons for a set
ExIconify.Sets.samples("lucide")

# Get set info
ExIconify.Sets.info("lucide")

Cache Management

# Get cache stats
ExIconify.cache_stats()
#=> %{size: 42, memory_bytes: 12345}

# Clear cache
ExIconify.clear_cache()

How It Works

  1. When you request an icon, ExIconify first checks the ETS cache
  2. If not cached, it fetches the SVG from the Iconify API
  3. The SVG is normalized (colors set to currentColor) and cached
  4. Subsequent requests return the cached version instantly

Icons are cached for 24 hours by default and automatically cleaned up.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE for details.

Credits

  • Iconify - The amazing icon framework
  • All the icon set creators and maintainers