Skip to main content
go-swarm-icons
On this page

Core Concepts

Covers providers, prefixes, immutable icons, attribute layering, caching, and accessibility defaults.

Before diving into configuration, it helps to understand a few ideas that shape how the library works. None of this is required to render an icon (the Quick Start covers that), but it makes the rest of the documentation clearer.

Providers

A provider is any type that implements three methods: Get(name), Has(name), and All(). Each provider knows how to load icons from one source (a directory, a JSON file, an HTTP API, or another provider).

Register a provider under a prefix, and the manager routes icon lookups to it:

Go
import (
swarmicons "github.com/frostybee/go-swarm-icons"
"github.com/frostybee/go-swarm-icons/lucide"
)
manager := swarmicons.Default("lucide", lucide.Provider())

The library ships with four implementations plus an embedded Lucide set. See the Providers section for details on each.

Prefixes

Icon names follow the "prefix:name" format. The prefix tells the manager which provider to query:

Go
icon, _ := manager.Get("lucide:home") // explicit prefix → lucide provider
icon, _ = manager.Get("tabler:star") // explicit prefix → tabler provider
icon, _ = manager.Get("home") // bare name → default prefix

A bare name (no colon) resolves against the default prefix. swarmicons.Default("lucide", ...) sets "lucide" as the default, so manager.Get("home") and manager.Get("lucide:home") return the same icon.

Icon as value object

Every Icon is immutable. Fluent methods like Size(), Class(), and Rotate() return a new *Icon with the change applied. The original is never modified.

Go
base, _ := manager.Get("home")
large := base.Size(48)
styled := base.Size(24).Class("text-blue").Fill("currentColor")
// base is unchanged. large and styled are independent copies.

This makes it safe to store a base icon and derive variants from it across goroutines.

Attribute layers

When the manager resolves an icon, five layers of attributes merge in order. Each layer overrides the one before it, except for class, which always concatenates.

Priority Layer Source
1 (lowest) Icon defaults viewBox, width, height from the parsed SVG
2 Global defaults DefaultAttributes() in the config builder
3 Prefix attributes PrefixAttributes("tabler", ...) in the config builder
4 Suffix attributes PrefixSuffix("heroicons", "solid", ...) in the config builder
5 (highest) Caller attributes Passed to manager.Get() or set by fluent methods

SVG sanitization

Every icon is sanitized automatically, regardless of source. A nine-stage pipeline strips XML comments, <script> elements, on* event handlers, javascript: URIs, external references in <use> and <image>, and several other XSS vectors.

There is nothing to configure. Sanitization runs at parse time, before the icon enters the cache. The SVG Sanitization internals page documents each stage.

Caching

Each provider caches icons internally using a sync.RWMutex-protected map. The first Get() call for a given icon name pays the load cost (file read, JSON lookup, or HTTP request). Every subsequent call returns the cached copy.

Accessibility

The renderer injects ARIA attributes automatically based on what the icon carries:

  • Decorative icon (no aria-label or aria-labelledby): adds aria-hidden="true" and focusable="false".
  • Labeled icon (has aria-label, aria-labelledby, or an explicit role): sets role="img" if no role is present. Does not add aria-hidden.

To make an icon labeled, add a title and an ARIA label:

Go
icon.Title("Home").Attr(map[string]string{"aria-label": "Home"})

Existing attributes are never overwritten. An aria-hidden="false" or role="button" set by a caller is preserved as-is.

What's next

  • Providers: learn about each provider type and when to use it
  • Guides: task-focused walkthroughs for manipulation, attributes, aliases, Goldmark, sprites, and caching
Edit this page

Last updated: