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

JSON Collection Provider

Load Iconify JSON icon sets from disk or embed them for production deployments.

This is the recommended way to use Iconify icon sets in production. Download the sets ahead of time, load them from disk or embed them in the binary, and resolve icons with no HTTP requests at runtime.

What it does

JsonCollectionProvider loads icons from an Iconify JSON collection file. The JSON is parsed once on first access via sync.Once, and resolved icons are cached in memory for all subsequent calls.

When to use it

Reach for this provider when working with Iconify-format JSON icon sets (Tabler, Heroicons, Material Design, and 200+ others), whether loaded from disk at runtime or embedded in the binary via go:embed. It handles alias resolution, per-icon transforms, and root-level dimension defaults automatically.

For .svg files on disk, see Directory Provider. For the pre-bundled Lucide set, see Embedded Lucide.

Setup

From a file on disk

Go
import swarmicons "github.com/frostybee/go-swarm-icons"
p, err := swarmicons.NewJsonCollectionProvider("./tabler.json")
if err != nil {
log.Fatal(err)
}
manager := swarmicons.Default("tabler", p)

From embedded bytes

Use go:embed to bundle the JSON file in the binary:

Go
import (
_ "embed"
swarmicons "github.com/frostybee/go-swarm-icons"
)
//go:embed icons.json
var iconsData []byte
func main() {
p := swarmicons.NewJsonCollectionFromBytes(iconsData)
manager := swarmicons.Default("icons", p)
}

NewJsonCollectionFromBytes does not return an error. The JSON is parsed lazily on the first call to Get, Has, or All.

Config builder

Go
import swarmicons "github.com/frostybee/go-swarm-icons"
manager, err := swarmicons.NewConfig().
AddJsonCollection("tabler", "./tabler.json").
DefaultPrefix("tabler").
Build()

Options & behavior

Lazy parsing

The JSON collection is not parsed at construction time. Parsing happens once, on the first call to Get(), Has(), or All(), using sync.Once. All subsequent calls use the parsed data without re-parsing.

If the JSON is malformed or missing the "icons" key, the provider returns false from Get() and Has(), and nil from All().

JSON schema

The provider expects the Iconify JSON format:

JSON
{
"prefix": "tabler",
"width": 24,
"height": 24,
"icons": {
"home": {
"body": "<path d=\"...\"/>",
"width": 24,
"height": 24
},
"alert": {
"body": "<path d=\"...\"/>"
}
},
"aliases": {
"house": {
"parent": "home"
},
"arrow-right": {
"parent": "arrow-left",
"hFlip": true
}
}
}
  • icons (required): map of icon name to Iconify icon entries. Each entry has a body (SVG inner content) and optional width, height, left, top, hFlip, vFlip, rotate fields. When the provider builds an Icon from an entry, it applies the rotation (quarter turns, 0-3) and flip transforms, constructs the viewBox attribute, and sanitizes the body; an entry with an empty body yields ErrInvalidSVG.
  • aliases (optional): map of alias name to an object with a parent field and optional override fields.
  • Root-level width/height: default dimensions inherited by icons that omit their own.

Alias resolution

Aliases reference a parent icon (or another alias) and can override transform fields:

Field Type Effect
parent string Name of the parent icon or alias (required).
hFlip *bool Horizontal flip. Pointer type allows explicit false to override a parent's true.
vFlip *bool Vertical flip. Same pointer semantics.
rotate *int Rotation in quarter turns (0-3).
width *int Override width.
height *int Override height.
body string Replace the parent's SVG body entirely.

Aliases can chain (alias → alias → icon). Resolution stops at a depth of 10 to prevent infinite loops. A chain deeper than 10 levels returns false from Get().

Icon listing

All() returns the names of all icons and all aliases in the collection. Both are treated as valid icon names.

Caching

Resolved icons are cached in a thread-safe sync.RWMutex-protected map. The first Get() for a name resolves the icon (including alias chains and transforms), caches the result, and returns it. Subsequent calls return the cached *Icon directly.

Examples

Load from file

Go
import (
"fmt"
"log"
swarmicons "github.com/frostybee/go-swarm-icons"
)
func main() {
p, err := swarmicons.NewJsonCollectionProvider("./tabler.json")
if err != nil {
log.Fatal(err)
}
manager := swarmicons.Default("tabler", p)
icon, err := manager.Get("home")
if err != nil {
log.Fatal(err)
}
fmt.Println(icon.ToHTML())
}

Embed with go:embed

Go
import (
_ "embed"
"fmt"
swarmicons "github.com/frostybee/go-swarm-icons"
)
//go:embed heroicons.json
var heroiconsData []byte
func main() {
p := swarmicons.NewJsonCollectionFromBytes(heroiconsData)
manager := swarmicons.Default("heroicons", p)
icon, err := manager.Get("check-circle")
if err != nil {
fmt.Println("not found")
return
}
fmt.Println(icon.Size(20).ToHTML())
}

Discover all JSON sets in a directory

The Config builder can scan a directory for *.json files and register each as a provider using the filename (without extension) as the prefix:

Go
import swarmicons "github.com/frostybee/go-swarm-icons"
manager, err := swarmicons.NewConfig().
DiscoverJsonSets("./json/").
DefaultPrefix("tabler").
Build()

Given a ./json/ directory containing tabler.json and mdi.json, this registers two providers under prefixes "tabler" and "mdi".

Choosing a provider

Provider Source Network Disk Caching Best for
Directory .svg files No Yes Per-icon on first access Custom/brand icons
JSON Collection Iconify JSON No Yes (or go:embed) Full parse on first call Production icon sets
Iconify API HTTP API Yes No Per-icon on first fetch Prototyping, unknown sets
Chain Multiple providers Depends Depends Per-provider Local-first + fallback
Embedded Lucide go:embed in binary No No Full parse on first call Quick start, Lucide-only

See also

Edit this page

Last updated: