Fonts are the exception. A font is a single file placed in the
Fonts folder, with no manifest and no folder of its own. See Fonts below.Required fields
Each of these must be present and not undefined. Otherwise the addon is rejected when it loads.string
required
A unique identifier for the addon. It is the addon’s key in every manager operation and its storage namespace, so keep it the same across versions.
string
required
The human-readable name shown in settings.
string
required
A short summary of what the addon does.
AddonAuthor[]
required
A non-empty array of authors. An empty array fails validation, the same as a missing field.
string
required
The addon’s version. Increase it on every release so clients can detect updates.
string
required
The entry point the bundle is built from. Themes ignore this field. See Themes below.
Optional fields
Used for display and updates. You can leave them out.string | { uri: string }
The addon’s icon: an asset name, or an object with a
uri for a remote image.string
A URL Unbound checks to discover newer versions.
string
Where the addon’s bundle is hosted.
Example
manifest.json
You reference the
id in several places:- Manager calls such as
plugins.toggle('my-plugin'). - Your storage store name.
- The addon’s entry in the enabled-state map.
Per-addon details
Every kind uses the same manifest shape, but each needs different files on disk and uses different fields.- At startup, the loader scans the
Plugins,Themes, andFontsfolders. - Icon packs are installed by the client under
Unbound/Icons.
Plugins
Plugins
A plugin is a directory inside
Plugins that contains a manifest.json. The loader skips entries that aren’t directories or have no manifest.main is required and must resolve to a real file. It resolves in one of two ways:- A value starting with
/is treated as an absolute path and used as-is. - Anything else resolves relative to the plugin’s own folder.
Themes
Themes
A theme is a directory that contains both a
manifest.json and a bundle.json. The bundle file name is fixed. The loader looks for exactly bundle.json next to the manifest, and skips the theme if that file is missing or isn’t a JSON object.While a theme is active, its id is stored as applied. Only one theme is applied at a time, and this value is how Unbound remembers which one. The palette and background live in bundle.json, not in the manifest. See Theme Types.Icon Packs
Icon Packs
An icon pack is a folder of image files with the same layout as Discord’s asset tree, installed under How
Unbound/Icons/<id>. It uses the shared manifest above, plus two fields of its own:'icon-pack'
Marks the manifest as an icon pack. If the field is present at install time, it must be
'icon-pack', or the install is rejected.'github' | 'other'
How the pack’s files are fetched. If omitted, it is inferred from
main: a github.com URL means github, and anything else means other.main is used depends on source:github:mainis the repo URL, optionally with a/tree/<branch>/<path>suffix. Unbound downloads the images in that tree into the pack folder.other: the pack installs through the shared bundle path, like any other addon.
Fonts
Fonts
A font has no manifest and no folder. It is a single font file placed directly in the
Fonts directory. The loader registers it under the full name stored inside the font file, not under its file name.Registering a font does not apply it. A font only takes effect through the unbound.font-states setting, which maps a font family name to the name of the font to use in its place. See Settings for that key.