If the project has three icons, paste the SVG. A library adds a dependency, an abstraction layer, and a concept or two to learn. For a handful of static icons, that trade-off is not worth it.
But icon needs tend to grow. A second set appears, accessibility requirements land, someone asks for runtime icon resolution from user content, and suddenly the project has a scattered pile of SVG strings, no consistent sizing, and no sanitization. That is the point where a library pays for itself.
When inline SVG is enough
- The project uses fewer than ~10 icons, all from one set.
- Icons never change at runtime (no user-selected icon names).
- Accessibility attributes are applied by hand and reviewed in a checklist.
- Nobody needs to swap icon sets without a code change.
Nothing wrong with any of that. Inline SVG has the least overhead, and least overhead wins when it works.
When go-swarm-icons fits
- Multiple icon sets in one project: Register each set under a prefix (
"lucide","tabler","heroicons") and resolve them with onemanager.Get("prefix:name")call. No separate loading logic per set. - Static Site Generator (SSG) pipelines: Render hundreds or thousands of pages concurrently. Every provider is thread-safe, every
Iconis immutable, and caching is built in. - Runtime icon resolution: Content editors or CMS templates reference icons by name. The manager resolves them, applies sanitization, and returns safe HTML without trusting the input.
- Consistent accessibility and sanitization: ARIA attributes are injected automatically (decorative icons get
aria-hidden="true", labeled icons getrole="img"). A nine-stage sanitization pipeline strips scripts, event handlers, and external references from every icon, regardless of source.
Comparison
| Dimension | Inline SVG | Icon font | go-swarm-icons |
|---|---|---|---|
| Setup cost | Zero | Font file + CSS | go get + 3 lines |
| Runtime performance | No overhead | Font rendering | Cache lookup per icon |
| Accessibility | Manual aria-* |
Limited (font glyphs) | Automatic ARIA injection |
| SVG sanitization | None (trust the source) | N/A | Automatic, every icon |
| Dead code | All SVGs ship | Full font ships | Load only what you resolve |
| Dynamic resolution | Hardcoded markup | CSS class swap | manager.Get(name) by string |
Which modules to install
Three independent Go modules. Install only what the project needs.
- Lucide icons only: install the core module and the Lucide submodule, then follow the Quick Start.
- Other Iconify sets (Tabler, Heroicons, Material Design, ...): install the core module, download the sets with the
swarm-iconsCLI (swarm-icons json download tabler), and load them withNewJsonCollectionProvider. For prototyping,NewIconifyProvidercan fetch from the API at runtime instead. - Markdown pipeline: add the Goldmark submodule for
:icon[prefix:name]syntax in Markdown content.
What's next
- Installation: install the modules and set up import aliases
- Quick Start: render an icon in eight lines of Go