Skip to content

Icon Packs

Use iconpack to generate a Go package and SVG sprite from the icons you choose. The generated package renders through Goshtoso’s Icon component and lives in your application, alongside the source records and licenses.

Example: Bootstrap Icons

These icons come from a generated Bootstrap Icons package. The alarm has an accessible label; the Bootstrap logo is decorative because the adjacent text supplies its meaning.

Bootstrap Icons
Alarm
Bootstrap

Generate from an Assets release

You can generate a pack from an Arai Hû Assets release or define your own sources in .iconpack.yaml, as shown in the next section. For a release archive, supply its SHA-256 checksum and the checksums for its catalog and release metadata. Select icons using the canonicalName field in the release’s catalog.json file. Pass that field’s value to -name; for example, -name ui-hi-16-solid-check selects the check icon in the command below.

Generate appicons
go run github.com/araihu/goshtoso/cmd/iconpack@latest \
  -release-archive ./araihu-assets-v0.2.0.tar.gz \
  -archive-sha256 "$ASSETS_ARCHIVE_SHA256" \
  -release v0.2.0 \
  -catalog-sha256 "$CATALOG_SHA256" \
  -release-json-sha256 "$RELEASE_JSON_SHA256" \
  -checksums-sha256 "$CHECKSUMS_SHA256" \
  -name brand-developer-icons-tRPC \
  -name ui-hi-16-solid-check \
  -out ./internal/appicons \
  -package appicons \
  -const-prefix Icon \
  -sprite-url /assets/icons/appicons/sprite.svg

For an extracted release directory, replace -release-archive with -release-root and omit -archive-sha256. Create the parent directory, internal in this example, before running the command. The generator writes the output directory atomically.

Define sources with .iconpack.yaml

To combine icons from GitHub repositories or individual SVG URLs, list the sources in .iconpack.yaml. The example below selects one Heroicons icon and one Bootstrap icon, with a license for each source.

.iconpack.yaml
schemaVersion: 1
sources:
  - id: heroicons
    url: https://github.com/tailwindlabs/heroicons/tree/master/src
    packName: heroicons
    paths:
      - 16/solid/academic-cap.svg
    license: MIT
    licensePath: LICENSE
    licenseUrl: https://raw.githubusercontent.com/tailwindlabs/heroicons/master/LICENSE
  - id: bootstrap
    kind: file
    url: https://raw.githubusercontent.com/twbs/icons/v1.11.3/icons/alarm.svg
    path: alarm.svg
    license: MIT
    licensePath: LICENSE
    licenseUrl: https://raw.githubusercontent.com/twbs/icons/v1.11.3/LICENSE.md
Record source checksums and generate
go run github.com/araihu/goshtoso/cmd/iconpack@latest \
	  -config ./.iconpack.yaml -trust \
	  -out ./internal/appicons -package appicons \
	  -const-prefix Icon -sprite-url /assets/icons/appicons/sprite.svg

The first run uses -trust to record the downloaded sources in .iconpack.lock.yaml. Review and retain that lock file, then omit -trust on subsequent runs. The tool checks later downloads against the recorded bytes and fails if they change.

For a GitHub source, paths selects individual SVGs; omitting it includes every SVG in the tree. Names combine the pack name and normalized path, such as heroicons-16-solid-academic-cap. If you omit packName, GitHub sources use the repository name and other sources use their id.

Serve and render icons

Serve the generated sprite at the same-origin URL passed to the generator. Import the generated package and pass a symbol to its Icon function. Replace example.com/myapp below with your module path. This example uses the tRPC icon selected from the Assets release above.

Use the generated typed symbol
import (
    "github.com/araihu/goshtoso/components/icon"
    "example.com/myapp/internal/appicons"
)

// Route /assets/icons/appicons/sprite.svg to ./internal/appicons/sprite.svg.
templ ProviderIcon() {
    @appicons.Icon(appicons.Config{
        Symbol:    appicons.IconBrandDeveloperIconsTRPC,
        Size:      icon.SizeLG,
        Label:     "tRPC",
        RootClass: "text-primary",
    })
}

Use the generated constants directly. The generator converts catalog names into valid Go identifiers while preserving the original names and sprite symbols in their values. For example, NameBrandDeveloperIconsTRPC contains brand-developer-icons-tRPC, and IconBrandDeveloperIconsTRPC identifies the catalog’s devicon-trpc symbol.

Look up icons by name

If your application stores icon names in configuration, convert the value to the generated Name type and call Lookup. It returns the glyph and a boolean indicating whether the pack contains that name. This example treats a missing icon as a configuration error.

Resolve an exact canonical name
func IconForName(name appicons.Name) icon.Instance {
    glyph, ok := appicons.Lookup(name)
    if !ok {
        panic("icon is not in this generated pack")
    }
    return appicons.Icon(appicons.Config{
        Symbol: glyph.Symbol,
        Label:  string(glyph.CanonicalName),
    })
}

Use an existing source manifest

If you already have a JSON or YAML source manifest with per-file SHA-256 checksums, you can continue using it. For a new pack, use .iconpack.yaml to download and verify sources with the same command.

Generate from an existing hashed source manifest
go run github.com/araihu/goshtoso/cmd/iconpack@latest \
	-source-root ./vendor/bootstrap-icons \
	-source-manifest ./bootstrap-icons.goshtoso.json \
	-name bootstrap-icons-alarm \
	-out ./internal/bootstrapicons -package bootstrapicons \
	-const-prefix Icon -sprite-url /assets/icons/bootstrapicons/sprite.svg

The generator verifies each source file against the SHA-256 checksum in the manifest.

Generated files

Keep the generated files with your application. They contain the icons, Go API, source records, and license notices needed to use and redistribute the pack.

sprite.svg
Only the selected SVG symbols, with the catalog sprite symbols preserved literally.
icons_gen.go
Typed Name, Glyph, icon.Symbol constants, Lookup, Config, SpriteURL, and Icon.
manifest.json
Release, source kind, archive identity, selected assets, generated identifiers, and output hashes.
provenance.json + PROVENANCE/
Per-family source and license references copied from the verified release.
licenses/ + NOTICE
The notices required to redistribute the selected assets.

Accessibility, color, and updates

  • Use a relative same-origin sprite URL. HTTPS pages must not depend on an HTTP sprite or cross-origin <use> behavior.
  • Give icons that convey meaning a descriptive Label. Set Decorative: true on purely visual icons; this hides them from assistive technology.
  • Do not recolor protected brand assets. Monochrome assets can inherit currentColor through your normal Goshtoso classes.
  • When updating, generate a new versioned output and sprite route, verify the new manifest, then switch the application import and route together. Retain the previous output as a rollback artifact until the deployment is confirmed.

See the Icon documentation for sizing, labels, and decorative icons.