200,000+ Icons
Access any of the 200+ Iconify icon sets at runtime or pre-download them for offline use. No Node.js required.
A framework-agnostic PHP library for rendering SVG icons
200,000+ icons from Iconify · Local SVG · JSON collections · No Node.js required
$ composer require frostybee/swarm-icons Mix and match providers to suit your project
Download sets once via CLI. Icons are lazy-loaded and PSR-16 cached. Works fully offline after setup.
// 1. Download sets once . no Node.js required
// php bin/swarm-icons json:download mdi tabler heroicons
use Frostybee\SwarmIcons\SwarmIcons;
use Frostybee\SwarmIcons\SwarmIconsConfig;
$manager = SwarmIconsConfig::create()
->discoverJsonSets() // auto-register all downloaded sets
->cachePath('/var/cache/icons')
->build();
SwarmIcons::setManager($manager);
// Render icons anywhere in your PHP app
echo swarm_icon('mdi:home', ['class' => 'w-6 h-6']);
echo swarm_icon('tabler:star', ['aria-label' => 'Favorite']);
echo swarm_icon('heroicons:user'); // 1. Download sets once . no Node.js required
// php bin/swarm-icons json:download mdi tabler heroicons
use Frostybee\SwarmIcons\SwarmIcons;
use Frostybee\SwarmIcons\SwarmIconsConfig;
$manager = SwarmIconsConfig::create()
->discoverJsonSets() // auto-register all downloaded sets
->cachePath('/var/cache/icons')
->build();
SwarmIcons::setManager($manager);
// Render icons anywhere in your PHP app
echo swarm_icon('mdi:home', ['class' => 'w-6 h-6']);
echo swarm_icon('tabler:star', ['aria-label' => 'Favorite']);
echo swarm_icon('heroicons:user'); Mix providers, set defaults, configure suffix rules, define aliases, and set fallbacks — all in one fluent chain.
use Frostybee\SwarmIcons\SwarmIconsConfig;
$manager = SwarmIconsConfig::create()
->addIconifySet('heroicons')
->addIconifySet('tabler')
->addDirectory('custom', __DIR__ . '/resources/icons')
->addJsonCollection('mdi', __DIR__ . '/resources/mdi.json')
->cachePath('/var/cache/icons')
->defaultPrefix('heroicons')
->defaultAttributes(['class' => 'icon'])
->prefixAttributes('tabler', ['stroke-width' => '1.5'])
->prefixSuffix('heroicons', 'solid', ['fill' => 'currentColor'])
->prefixSuffix('heroicons', 'outline', ['stroke' => 'currentColor', 'fill' => 'none'])
->alias('check', 'heroicons:check-circle')
->fallbackIcon('heroicons:question-mark-circle')
->ignoreNotFound()
->build(); use Frostybee\SwarmIcons\SwarmIconsConfig;
$manager = SwarmIconsConfig::create()
->addIconifySet('heroicons')
->addIconifySet('tabler')
->addDirectory('custom', __DIR__ . '/resources/icons')
->addJsonCollection('mdi', __DIR__ . '/resources/mdi.json')
->cachePath('/var/cache/icons')
->defaultPrefix('heroicons')
->defaultAttributes(['class' => 'icon'])
->prefixAttributes('tabler', ['stroke-width' => '1.5'])
->prefixSuffix('heroicons', 'solid', ['fill' => 'currentColor'])
->prefixSuffix('heroicons', 'outline', ['stroke' => 'currentColor', 'fill' => 'none'])
->alias('check', 'heroicons:check-circle')
->fallbackIcon('heroicons:question-mark-circle')
->ignoreNotFound()
->build(); Every icon method returns a new instance. Chain size, class, stroke, fill, and custom attributes safely.
// Icons are immutable value objects . every method returns a new instance
$icon = $manager->get('heroicons:home');
echo $icon->size(32)->class('text-blue-500');
echo $icon->size(24)->strokeWidth(1.5)->fill('none');
// Fluent chaining
echo $manager->get('tabler:star')
->size(20)
->class('text-yellow-400')
->attr('aria-label', 'Favorite');
// Conditional rendering
if ($manager->has('custom:logo')) {
echo $manager->get('custom:logo', ['aria-label' => 'Logo']);
} // Icons are immutable value objects . every method returns a new instance
$icon = $manager->get('heroicons:home');
echo $icon->size(32)->class('text-blue-500');
echo $icon->size(24)->strokeWidth(1.5)->fill('none');
// Fluent chaining
echo $manager->get('tabler:star')
->size(20)
->class('text-yellow-400')
->attr('aria-label', 'Favorite');
// Conditional rendering
if ($manager->has('custom:logo')) {
echo $manager->get('custom:logo', ['aria-label' => 'Logo']);
} Dedicated Twig extension with icon(), icon_exists(), and get_icon() functions.
{# Register once in your bootstrap #}
{# $twig->addExtension(new SwarmIconsExtension(...)); #}
{{ icon('heroicons:home') }}
{{ icon('heroicons:user', {class: 'w-6 h-6', 'aria-label': 'Profile'}) }}
{% if icon_exists('custom:logo') %}
{{ icon('custom:logo') }}
{% endif %}
{# Fluent API via get_icon() #}
{% set star = get_icon('tabler:star') %}
{{ star.size(24).class('text-yellow-400') }} {# Register once in your bootstrap #}
{# $twig->addExtension(new SwarmIconsExtension(...)); #}
{{ icon('heroicons:home') }}
{{ icon('heroicons:user', {class: 'w-6 h-6', 'aria-label': 'Profile'}) }}
{% if icon_exists('custom:logo') %}
{{ icon('custom:logo') }}
{% endif %}
{# Fluent API via get_icon() #}
{% set star = get_icon('tabler:star') %}
{{ star.size(24).class('text-yellow-400') }} Access any of the 200+ Iconify icon sets at runtime or pre-download them for offline use. No Node.js required.
Strict types, fully typed codebase, immutable value objects, PSR-4 autoloading, PHPStan Level 8.
Bring your own cache or use the built-in file cache. Icons are cached forever by default — zero overhead after first render.
Built-in sanitizer strips <script>, on* handlers, javascript: URIs, and external resource references.
A dedicated Twig extension with icon(), icon_exists(), and get_icon(). Laravel Blade works via the global helper.
Decorative icons get aria-hidden="true" automatically. Add aria-label to mark icons as meaningful.