How icon packs work
Discord refers to each icon by name and resolves it to a bundled asset. An icon pack hooks that resolution: for every icon name it provides a replacement for, Unbound redirects the asset to your image instead of Discord’s. Names you don’t override fall through to Discord’s originals, so a pack can be as small as a handful of icons or as complete as you like. Internally each overridden asset carries aniconPackPath (where your replacement image lives) and an iconPackScale (the density it’s authored at), which is how Unbound resolves your image at the right resolution.
An icon pack overrides icons by name. The same asset names the assets module discovers are the ones you target, so the naming you see there is the naming a pack overrides.
What an icon pack ships
Unlike a plugin, a pack ships no code. It’s a folder of image files mirroring Discord’s asset tree, installed underUnbound/Icons/<id> (see iOS for where that is on device).
Manifest
Metadata identifying the pack: name, authors, version, plus
type and source.Assets
How Discord’s icons are named and discovered: the names a pack overrides.
File layout
Each image mirrors the asset it replaces. The path is the asset’s own location with the leadingassets/ stripped, then the asset name, then its extension:
@2x, @3x suffix, and the bare name is scale 1. Unbound picks the highest scale present for each asset, so shipping only an @3x file is fine. An asset with no matching file in the pack keeps Discord’s original.
Installing
Packs install from a manifest URL. Thesource field decides how the files are fetched:
github
github
main is the repo URL, optionally narrowed with /tree/<branch>/<subpath>. Unbound reads the repo’s file tree and downloads every file under that path into the pack folder. If source is omitted and main is a github.com URL, this is what’s used.other
other
The pack installs through the same bundle download path as any other addon.