Skip to content

widget.json

Every widget has a widget.json in its folder. Umbra validates it when the widget loads, when it’s installed, and in CI for catalog widgets (node scripts/catalog.mjs). Add the $schema line and your editor validates and completes it as you type:

"$schema": "https://raw.githubusercontent.com/AmineChr54/umbra/main/schemas/widget.schema.json"
{
"$schema": "https://raw.githubusercontent.com/AmineChr54/umbra/main/schemas/widget.schema.json",
"id": "weather",
"name": "Weather",
"description": "Current temperature and conditions for one city.",
"author": "your-github-name",
"version": "1.0.0",
"entry": "index.html",
"preview": "preview.png",
"width": 300,
"height": 160,
"defaultPosition": { "x": 24, "y": 420 },
"permissions": { "hosts": ["api.open-meteo.com"] },
"options": {
"city": { "label": "City", "type": "text", "default": "Berlin", "hint": "Shown under the field" },
"units": { "label": "Units", "type": "select", "default": "c",
"choices": [{ "value": "c", "label": "Celsius" }, { "value": "f", "label": "Fahrenheit" }] },
"decimals": { "label": "Decimals", "type": "number", "default": 0, "min": 0, "max": 2, "step": 1 },
"compact": { "label": "Compact mode", "type": "toggle", "default": false }
}
}
Field Rules
id Equals the folder name. 2 to 40 characters: lowercase letters, digits and dashes, starting with a letter or digit (^[a-z0-9][a-z0-9-]{1,39}$).
name, description, author Required, non-empty.
version Required, like 1.2.3. Bump it on every change: it’s how users get an Update button.
changelog Optional, up to 500 characters: what changed. Shown when an update asks for new access and carried in the catalog index.
entry The page to open. Default index.html.
preview Screenshot for Browse. Recommended: a 2x capture on a black background.
icon Optional tab icon for tab groups: a 64×64 PNG, light grey on transparent.
width, height Integers 80 to 1200, in logical pixels. Umbra scales them for the display’s DPI and the user’s size setting.
defaultPosition { "x", "y" } from the top left of the primary work area, in logical pixels. Omit to start at the top right.
themeable Default true. false keeps your own look and ignores the user’s theme.
options The settings form in My widgets, in this order. See below.
permissions What the widget may reach. See below.
type Extra fields Value
text hint string
number min, max, step number
select choices: a list of { "value", "label" } (required) the chosen value
toggle none boolean

Every option has a label and a default. Read values in the page from umbra.options; they update live through umbra.onSettings. Users (and scripts) can change them with umbractl set <id> <option> <value>, which types the value by the schema.

Field Meaning
hosts Every HTTPS hostname the widget may reach. All other requests are blocked (fetch, XHR, images, scripts, fonts). Use [] for offline widgets.
notifications true to use umbra.notify. The user must also switch “Allow notifications” on for the widget in Settings (off by default).
media "read" (umbra.media.nowPlaying) and/or "control" (umbra.media.control).
system Any of "cpu", "memory", "network", for umbra.system().
commands Local programs the widget may start with umbra.run. Every command needs your approval. See Running local commands.

Browse shows every permission on the widget’s card, and an update that adds any of them needs the user’s approval. See Sandbox and permissions.

A widget folder may contain .html .js .mjs .css .svg .png .jpg .webp .gif .woff .woff2 .ttf .otf .json .txt .md files, 5 MB in total. File paths must be relative with forward slashes and no ... See widget.json schema for the machine-readable definition, and the SDK reference for the full details in one page.