# PhoenixIconify
[](https://hex.pm/packages/phoenix_iconify) [](https://hexdocs.pm/phoenix_iconify)
Inline [Iconify](https://iconify.design) SVGs for Phoenix and LiveView. Write a normal Phoenix component, let the compiler discover the icons you use, and ship only those icons with your app.
```heex
<.icon name="lucide:settings" class="size-5" />
```
PhoenixIconify gives Phoenix apps access to 200,000+ icons from 150+ icon sets without a client-side icon runtime. Browse icons at [icon-sets.iconify.design](https://icon-sets.iconify.design).
## Why PhoenixIconify
Most Iconify integrations load icons in JavaScript. PhoenixIconify keeps icons on the server:
- Icons are discovered from HEEx at compile time
- Only icons you use are fetched and stored
- Rendering is plain inline SVG
- No browser-side icon loader
- Works with LiveView diffs and `phx-*` attributes
- Dynamic icons can be pre-registered in config
It pairs naturally with Tailwind and Volt-powered Phoenix projects:
```heex
<button class="inline-flex items-center gap-2">
<.icon name="lucide:settings" class="size-4" />
Settings
</button>
```
## Installation
Add the dependency:
```elixir
def deps do
[
{:phoenix_iconify, "~> 0.1.0"}
]
end
```
Add the compiler:
```elixir
def project do
[
compilers: Mix.compilers() ++ [:phoenix_iconify]
]
end
```
Import the component in your web module:
```elixir
# lib/my_app_web.ex
defp html_helpers do
quote do
import PhoenixIconify, only: [icon: 1]
end
end
```
Now use icons in HEEx:
```heex
<.icon name="lucide:settings" class="size-5" />
```
## Usage
Use Iconify's standard `prefix:name` format:
```heex
<.icon name="lucide:home" class="size-5" />
<.icon name="mdi:account" class="size-6 text-blue-600" />
<.icon name="heroicons:check" class="size-4" />
```
Phoenix-style Heroicons names are supported too:
```heex
<.icon name="hero-user" class="size-6" />
<.icon name="hero-sun-mini" class="size-5" />
<.icon name="hero-sun-micro" class="size-4" />
```
Global attributes are forwarded to the SVG, including `phx-*`, `data-*`, and `aria-*`:
```heex
<.icon name="lucide:x" class="size-4" phx-click="close" data-testid="close" />
```
## Accessibility
Icons are decorative by default and render with `aria-hidden="true"`:
```heex
<.icon name="lucide:settings" class="size-5" />
```
For meaningful icons, provide `label` or `title`:
```heex
<.icon name="lucide:settings" label="Settings" />
<.icon name="lucide:settings" title="Settings" />
```
## Sizing
Use Tailwind's `size-*` utilities when possible:
```heex
<.icon name="lucide:settings" class="size-5" />
```
Or set SVG dimensions directly:
```heex
<.icon name="lucide:settings" size="20" />
<.icon name="lucide:settings" width="1em" height="1em" />
```
## Transformations
Iconify aliases can include transformations, and you can transform at render time:
```heex
<.icon name="lucide:arrow-right" rotate={1} />
<.icon name="lucide:arrow-right" flip="horizontal" />
<.icon name="lucide:arrow-right" h_flip />
<.icon name="lucide:arrow-right" v_flip />
```
## How it works
1. You write `<.icon name="lucide:settings" />`
2. The `:phoenix_iconify` compiler scans HEEx and `~H` sigils
3. Literal icon names are collected
4. Missing icons are fetched through Iconify
5. A JSON manifest is written to `priv/iconify/manifest.json`
6. At runtime, the component reads icons from the manifest and renders inline SVG
There is no client-side icon runtime and no JavaScript bundle impact.
## Dynamic icons
Compile-time discovery only works for literal names. If an icon name comes from assigns, a database, or user configuration, register the possible values:
```elixir
# config/config.exs
config :phoenix_iconify,
extra_icons: [
"lucide:check",
"lucide:x",
"lucide:alert-triangle"
]
```
Then dynamic usage works at runtime:
```heex
<.icon name={@status_icon} class="size-4" />
```
## Configuration
```elixir
config :phoenix_iconify,
extra_icons: ["lucide:check", "lucide:x"],
fallback: "lucide:circle-help",
warn_on_missing: true
```
Options:
- `:extra_icons` - icons to include even when they are not found by static discovery
- `:fallback` - icon to render when a requested icon is missing
- `:warn_on_missing` - log missing icon warnings, enabled by default
## Cache and manifest
PhoenixIconify stores:
- `priv/iconify/manifest.json` - icons used by your app
- `priv/iconify/sets/*.json` - cached icon sets
Useful tasks:
```bash
mix phoenix_iconify.prefetch # scan and fetch discovered icons
mix phoenix_iconify.audit # report discovered icons missing from the manifest
mix phoenix_iconify.clean # remove manifest icons no longer used
mix phoenix_iconify.list # list manifest icons
mix phoenix_iconify.stats # show manifest and cache stats
```
Cache tasks:
```bash
mix phoenix_iconify.cache fetch
mix phoenix_iconify.cache list
mix phoenix_iconify.cache clear
```
## Volt projects
For projects created with [Volt](https://hex.pm/packages/volt), PhoenixIconify is the server-rendered option:
```heex
<.icon name="lucide:settings" class="size-5" />
```
It does not use Volt's JavaScript pipeline. If you want client-side icon components instead, use the official npm packages (`iconify-icon`, `@iconify/react`, `@iconify/vue`, etc.) through Volt's normal package handling.
## License
MIT