Skip to content

Tutorial: Integrating SVG Icons with swarm-icons

In this tutorial, you will integrate the swarm-icons PHP library into your Slim MVC project. This library provides a framework-agnostic way to render inline SVG icons in your PHP views, with access to 27 pre-installed icon sets including Tabler, Heroicons, Lucide, Material Design Icons, and more.

By the end of this tutorial, you will be able to render icons like this in any view:

<h1><?= swarm_icon('tabler:home') ?> Dashboard</h1>

By completing this tutorial, you will be able to:

  • Install a PHP library via Composer in an existing Slim 4 project.
  • Register a new service in the application’s DI (Dependency Injection) container.
  • Configure the swarm-icons icon manager during the application bootstrap.
  • Render SVG icons in plain PHP views using the swarm_icon() helper function.
  • Customize icon attributes (size, CSS classes, fill, stroke) using the fluent API.
  • Search for available icons using the swarm-icons CLI tool.

  • A working Slim MVC project (e.g., brew-finder-app from the MVC lab).
  • Wampoon and VS Code.
  • Composer (bundled with Wampoon).
  • Basic familiarity with the Slim MVC project structure (controllers, views, routes).

Use these websites to browse and search for icons by name before using them in your project:


Objective: Add the swarm-icons library to your project dependencies.

Instructions:

  1. Open a terminal in VS Code and run the following Composer command to install the library:
Terminal window
"../../composer.bat" require frostybee/swarm-icons
  1. Verify the installation succeeded by checking that vendor/frostybee/swarm-icons/ exists in your project.

Objective: Add a Composer script alias so you don’t have to type the full path to the swarm-icons CLI every time.

Instructions:

  1. Open your composer.json file
  2. Add a "swarm" entry to the "scripts" section:
composer.json
"scripts": {
"start": "php -S localhost:8080 -t public public/index.php",
"swarm": "@php vendor/bin/swarm-icons",
"post-create-project-cmd": [
"@php -r \"file_exists('config/env.php') || copy('config/env.example.php', 'config/env.php');\""
]
}
  1. Save the file

Now instead of typing "../../php.bat" vendor/bin/swarm-icons every time, you can use the shorter:

Terminal window
"../../composer.bat" swarm -- <command>

Objective: Use the swarm-icons CLI to download the icon sets you want to use in your project.

Instructions:

  1. Run the following command to download a few popular icon sets into public/assets/svg-icons/:
Terminal window
"../../composer.bat" swarm -- json:download tabler heroicons lucide --dest=public/assets/svg-icons

This downloads the Tabler, Heroicons, and Lucide icon sets as JSON files into your project’s public/assets/svg-icons/ directory.

  1. To see all available popular sets and their download status, run:
Terminal window
"../../composer.bat" swarm -- json:download --list
  1. Alternatively, download all popular sets at once:
Terminal window
"../../composer.bat" swarm -- json:download --all --dest=public/assets/svg-icons

Step 4: Register the IconManager in the DI Container

Section titled “Step 4: Register the IconManager in the DI Container”

Objective: Add the icon manager as a service definition in the application’s dependency injection container and wire up the global swarm_icon() helper.

Instructions:

  1. Open your config/container.php file
  2. Add the following use statements at the top of the file, alongside the existing imports:
use Frostybee\SwarmIcons\SwarmIcons;
use Frostybee\SwarmIcons\IconManager;
use Frostybee\SwarmIcons\SwarmIconsConfig;
  1. Add the IconManager definition to the $definitions array, after the existing PDOService definition:
config/container.php
IconManager::class => function () {
$manager = SwarmIconsConfig::create()
->discoverJsonSets(APP_BASE_DIR_PATH . '/public/assets/svg-icons')
->cachePath(APP_BASE_DIR_PATH . '/var/cache/icons')
->defaultPrefix('tabler')
->defaultAttributes([
'width' => '24',
'height' => '24',
'fill' => 'none',
'stroke' => 'currentColor',
'stroke-width' => '2',
])
->build();
// Wire the icon manager to the global swarm_icon() helper.
SwarmIcons::setManager($manager);
return $manager;
},
  1. Open your config/bootstrap.php file and add the following line after the container is built (after ->build()) and before the App is retrieved:
config/bootstrap.php
// Boot the IconManager so the global swarm_icon() helper is available in views.
$container->get(\Frostybee\SwarmIcons\IconManager::class);

This eagerly resolves the IconManager from the container, which triggers the factory you defined above and calls SwarmIcons::setManager(). Without this line, the container definition is lazy: it only runs when something explicitly requests IconManager::class. The swarm_icon() helper would throw a “No IconManager instance set” error in your views.

  1. Save both files

What each configuration method does:

  • discoverJsonSets(path): Scans the given directory for JSON icon set files and registers them. We point it to public/assets/svg-icons/ where you downloaded your icon sets in Step 3.
  • cachePath(): Sets the directory for caching parsed icons. We use var/cache/icons following the project’s convention of storing runtime data in var/.
  • defaultPrefix('tabler'): Lets you write swarm_icon('home') instead of swarm_icon('tabler:home') for convenience.
  • defaultAttributes(): Sets sensible default SVG attributes for all icons. The values shown above are optimized for stroke-based icon sets like Tabler and Heroicons.
  • SwarmIcons::setManager($manager): Registers the manager globally so the swarm_icon() helper function works in all view templates.

Objective: Use the swarm_icon() helper to display SVG icons in your PHP view templates.

Instructions:

  1. Open an existing view file (e.g., app/Views/homeView.php)
  2. Add icons using the swarm_icon() helper with <?= ?> short echo tags:
app/Views/homeView.php
<?php
use App\Helpers\ViewHelper;
$page_title = 'Home';
ViewHelper::loadHeader($page_title);
?>
<div class="container mt-4">
<h1><?= swarm_icon('tabler:home') ?> Welcome</h1>
<nav class="mb-4">
<a href="#"><?= swarm_icon('tabler:users') ?> Users</a>
<a href="#" class="ms-3"><?= swarm_icon('tabler:settings') ?> Settings</a>
<a href="#" class="ms-3"><?= swarm_icon('heroicons:magnifying-glass') ?> Search</a>
</nav>
<p>
Status: <?= swarm_icon('tabler:circle-check', ['class' => 'text-success']) ?> Active
</p>
</div>
<?php
ViewHelper::loadJsScripts();
ViewHelper::loadFooter();
?>
  1. Save the file and visit the page in your browser

Key points:

  • swarm_icon() returns an Icon object that implements Stringable, so <?= ?> automatically outputs the <svg> markup.
  • The prefix:name format (e.g., tabler:home) identifies which icon set and which icon to render.
  • Since we set defaultPrefix('tabler') in Step 4, you can also write swarm_icon('home') as a shorthand for Tabler icons.
  • To use icons from other sets, specify the prefix explicitly: swarm_icon('heroicons:magnifying-glass'), swarm_icon('lucide:star').

Objective: Add basic CSS rules to control how icons appear within your page layout.

Instructions:

  1. Open (or create) your stylesheet at public/assets/css/style.css and add the following rules:
public/assets/css/style.css
/* Align inline SVG icons with surrounding text */
svg {
display: inline-block;
vertical-align: middle;
}
/* Color utility classes for icons */
.text-success { color: #28a745; }
.text-danger { color: #dc3545; }
.text-primary { color: #007bff; }
.text-warning { color: #ffc107; }
.text-muted { color: #6c757d; }
  1. Make sure the stylesheet is linked in app/Views/common/header.php:
app/Views/common/header.php
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $page_title ?></title>
<link href="<?= asset_url('/css/style.css') ?>" rel="stylesheet">
</head>
  1. Save both files and refresh the page

How icon colors work:

Because the defaultAttributes set stroke="currentColor", stroke-based icons (Tabler, Heroicons, Lucide) inherit the text color from their parent element. This means:

<!-- The icon inherits the red color from the CSS class -->
<span class="text-danger"><?= swarm_icon('tabler:alert-triangle') ?> Error</span>

Step 7: Customize Icons with the Fluent API

Section titled “Step 7: Customize Icons with the Fluent API”

Objective: Learn to modify icon attributes using method chaining for more advanced customization.

Instructions:

The swarm_icon() function returns an Icon object with a fluent API. You can chain methods to customize the icon before it is rendered:

Fluent API Examples
<!-- Change icon size -->
Small: <?= swarm_icon('tabler:star')->size(16) ?>
Medium: <?= swarm_icon('tabler:star')->size(24) ?>
Large: <?= swarm_icon('tabler:star')->size(48) ?>
<!-- Add CSS classes -->
<?= swarm_icon('tabler:heart')->class('text-danger')->size(32) ?>
<!-- Change fill color (for solid/fill-based icon sets) -->
<?= swarm_icon('fa6-solid:star')->fill('#ffc107')->size(32) ?>
<!-- Adjust stroke width (for outline/stroke-based icon sets) -->
<?= swarm_icon('tabler:alert-triangle')->strokeWidth(1.5)->size(32) ?>
<!-- Full method chain -->
<?= swarm_icon('tabler:rocket')
->size(48)
->class('text-primary')
->strokeWidth(1.5)
?>

Alternative: Pass attributes as an array:

Instead of chaining methods, you can pass an associative array as the second argument:

<?= swarm_icon('mdi:github', [
'width' => '32',
'height' => '32',
'class' => 'text-dark',
'fill' => 'currentColor',
]) ?>

Stroke-based vs Fill-based icon sets:

Rendering StyleIcon SetsKey Attribute
Stroke-based (outline icons)Tabler, Heroicons, Lucide, Phosphorstroke="currentColor"
Fill-based (solid icons)MDI, Font Awesome, Bootstrap Iconsfill="currentColor"

When using a fill-based icon set, override the default attributes:

<?= swarm_icon('mdi:home', ['fill' => 'currentColor', 'stroke' => 'none']) ?>

Objective: Use the swarm-icons command-line tool to discover available icons by name.

Instructions:

  1. Open a terminal in VS Code and run a search command:
Terminal window
"../../composer.bat" swarm -- icon:search tabler arrow

This searches the tabler icon set for all icons containing “arrow” in their name.

  1. Try more search examples:
Terminal window
# List all icons in the heroicons set
"../../composer.bat" swarm -- icon:list heroicons
# Search lucide icons for "user"
"../../composer.bat" swarm -- icon:search lucide user
# Search for "home" icons in the mdi set
"../../composer.bat" swarm -- icon:search mdi home

The output shows the full prefix:name format that you can copy directly into your swarm_icon() calls in your view code.


MethodDescriptionExample
size($px)Set width and height->size(32)
class($css)Add CSS classes->class('text-primary')
fill($color)Set fill color->fill('currentColor')
stroke($color)Set stroke color->stroke('#333')
strokeWidth($w)Set stroke width->strokeWidth(1.5)

Browse the full Tabler icon set on Iconify.

IconCode
Homeswarm_icon('tabler:home')
Userswarm_icon('tabler:user')
Searchswarm_icon('tabler:search')
Settingsswarm_icon('tabler:settings')
Editswarm_icon('tabler:edit')
Trashswarm_icon('tabler:trash')
Plusswarm_icon('tabler:plus')
Checkswarm_icon('tabler:check')
X (Close)swarm_icon('tabler:x')
Arrow Leftswarm_icon('tabler:arrow-left')
Starswarm_icon('tabler:star')
Heartswarm_icon('tabler:heart')
Eyeswarm_icon('tabler:eye')
Downloadswarm_icon('tabler:download')
Alert Triangleswarm_icon('tabler:alert-triangle')

IssueCauseFix
”No IconManager instance set” errorconfig/bootstrap.php is missing the SwarmIcons::setManager() callVerify that you added the line after the container is built (Step 4)
Icons render as empty spaceStroke/fill attributes do not match the icon set styleUse stroke="currentColor" for outline sets (Tabler, Heroicons) or fill="currentColor" for solid sets (MDI, FA)
Icons appear too large or too smallDefault size does not match your layoutUse ->size(16) or ->size(32) to adjust, or update defaultAttributes in container.php
Cache permission errorThe var/cache/ directory is not writableEnsure the web server has write permission to the var/ directory