Core Concepts
Before you go deep into configuration, it helps to understand a few ideas that shape how Swarm Icons works.
Providers load your icons
Section titled “Providers load your icons”A provider is a backend that knows how to fetch SVG data. You pick the right one depending on where your icons live:
DirectoryProviderreads.svgfiles from a folder on disk.JsonCollectionProviderreads pre-downloaded Iconify JSON files: fast, offline, recommended for production.IconifyProviderfetches icons on demand from the Iconify HTTP API.ChainProvidertries multiple providers in order until one finds the icon: great for local overrides with an API fallback.
You can mix and match. A typical setup might use JSON collections for your main sets, a directory for custom brand icons, and the API as a safety net.
Prefixes keep things organized
Section titled “Prefixes keep things organized”Every provider is registered under a prefix: a short string you choose. When you request an icon, you write prefix:name:
echo swarm_icon('tabler:home');echo swarm_icon('mdi:account');echo swarm_icon('custom:logo');The prefix tells Swarm Icons which provider to ask. The name tells that provider which icon to return.
If you set a default prefix, you can skip it for your most-used set:
->defaultPrefix('tabler')
echo swarm_icon('home'); // resolves to tabler:homeecho swarm_icon('mdi:account'); // other sets still need the prefixIcons are value objects
Section titled “Icons are value objects”When you call swarm_icon(), you get back an Icon object. It’s immutable and Stringable: you can echo it directly and get a full <svg> tag:
echo swarm_icon('tabler:home');// <svg aria-hidden="true" viewBox="0 0 24 24" ...>...</svg>Every fluent method returns a new instance, so the original stays unchanged:
$home = swarm_icon('tabler:home');
echo $home->size(32); // width="32" height="32"echo $home->class('text-blue-500'); // adds the classecho $home; // still the original, untouchedAttributes flow through layers
Section titled “Attributes flow through layers”Instead of passing the same class, stroke-width, or fill to every icon call, you set defaults once. Swarm Icons merges attributes in layers: each one can add or override what came before:
- Icon defaults: whatever the SVG file already has (
viewBox,xmlns, etc.) - Global defaults: applied to every icon you render
- Prefix defaults: applied to icons from a specific set
- Suffix defaults: applied based on the icon name’s ending (e.g.,
-solid,-outline) - Caller attributes: what you pass in the
swarm_icon()call
The last layer always wins. But CSS classes are special: they accumulate instead of replacing:
// You configured: defaultAttributes(['class' => 'icon'])// You configured: prefixAttributes('tabler', ['class' => 'w-6 h-6'])
echo swarm_icon('tabler:home', ['class' => 'text-blue']);// class="icon w-6 h-6 text-blue": all three are presentThis means you can set a base size for all Tabler icons, a shared .icon class globally, and still add per-instance classes without losing anything.
SVG content is sanitized
Section titled “SVG content is sanitized”Every SVG that passes through Swarm Icons is cleaned automatically. The parser strips <script> tags, on* event handlers, javascript: URIs, and external resource references. You don’t need to worry about XSS from untrusted SVG files.
Icons are cached
Section titled “Icons are cached”Providers that do expensive work (parsing JSON files, making HTTP requests) cache individual icons via PSR-16. The built-in file cache stores icons on disk with no expiration by default, so the heavy lifting only happens once.
->cachePath(__DIR__ . '/cache/icons')If you don’t configure a cache, Swarm Icons uses the system temp directory automatically.
Accessibility is automatic
Section titled “Accessibility is automatic”Decorative icons (most of them) get aria-hidden="true" added automatically. When you pass aria-label, the icon becomes meaningful and gets role="img" instead:
echo swarm_icon('home');// → aria-hidden="true" (decorative: hidden from screen readers)
echo swarm_icon('home', ['aria-label' => 'Home']);// → role="img" aria-label="Home" (meaningful: announced to screen readers)You don’t have to think about this unless you want to. The defaults do the right thing.
See also
Section titled “See also”- Configuration Builder: set up providers, caching, and defaults
- Fluent API: full reference for the
Iconvalue object