Skip to content

Theme packages (tavora.theme.json) ​

Status: first version, 2026-10-15. Themes are local only for now: Tavora's own ship with the app, and users can add their own to their themes folder. Publishing themes comes with the catalog.

A theme recolours Tavora and every module in it. It is data only: one tavora.theme.json with colour tokens and a corner radius. Tavora reads nothing else from the folder, so a theme cannot run code, add CSS or reach the app. Fonts and other assets are not supported yet.

Trying your own theme ​

  1. In Tavora, open Settings > Appearance and press New theme under "Your themes". It copies the Tavora theme, Dark and Light, into a my-theme folder in your themes folder and opens it. The same starter is in the repository as examples/theme-starter, and Tavora's own themes are good to copy too.
  2. Change the colours in its tavora.theme.json, and its id and name before you share it (ids starting with tavora. are reserved).
  3. Press Reload.

The theme shows up next to the official ones. If something is wrong, Appearance lists the folder and the first problem instead, for example a colour pair without enough contrast. Picking a theme applies it at once. Reset to Tavora Default always brings the default back.

json
{
  "id": "community.ash",
  "name": "Ash",
  "description": "Grey stone and a cold blue accent.",
  "author": "Your name",
  "version": "1.0.0",
  "variations": [
    {
      "id": "dark",
      "name": "Dark",
      "mode": "dark",
      "radius": 8,
      "colors": {
        "background": "#171412",
        "foreground": "#f2ece0",
        "…": "every token below"
      }
    }
  ]
}

Fields ​

Unknown fields are refused, so a typo fails loudly rather than being ignored.

FieldRequiredRules
$schemanoAny string. Ignored.
idyespublisher.theme-name, with the same rules as a module id. The user's choice is saved under it.
nameyes1 to 40 characters.
descriptionnoAt most 200 characters.
authornoAt most 60 characters.
versionyesmajor.minor.patch.
variationsyes1 to 4 variations. Users switch between them in Settings.

Each variation:

FieldRequiredRules
idyesLowercase letters, digits and -, at most 32 characters, unique in the theme. When a user switches themes, a variation with the same id (say light) is kept.
nameyes1 to 24 characters, shown in a segmented control.
modeyes"dark" or "light". Native menus, scrollbars and form controls follow it. Users can follow the system (the default): Tavora then shows the variation whose mode matches the system's light or dark setting, so a theme that comes in Dark and Light works with it unchanged.
contrastno"normal" (default) or "high". High-contrast variations need 7:1 for text instead of 4.5:1.
radiusnoCorner radius in px, a whole number from 4 to 12. Default 8.
colorsyesEvery token below, each as #rrggbb. No transparency. toast and toast-foreground may be left out.

Tokens ​

The names are shadcn-vue's semantic tokens plus four of Tavora's. Modules get the same values as --tavora-<name> properties and through ui.getTheme, and ui.onThemeChange tells them when the user picks another theme.

background, foreground, card, card-foreground, popover, popover-foreground, primary, primary-hover, primary-foreground, secondary, secondary-foreground, muted, muted-foreground, accent, accent-foreground, destructive, border, input, ring, rail, success, warning, info, toast, toast-foreground.

toast is the background of the notification pills and toast-foreground the text on them. Both are optional: a theme that leaves them out gets a flipped pill, foreground as the background and background as the text, and Tavora fills the two tokens in before modules see them.

Contrast rules ​

Tavora checks every variation against the colour pairs it really draws. Text needs 4.5:1 (7:1 in a high-contrast variation), and outlines and the focus ring need 3:1:

  • Text: foreground on background and rail; card-foreground, popover-foreground, secondary-foreground and accent-foreground on their surfaces; muted-foreground on background, card and muted; primary-foreground on primary and primary-hover; primary on background and card; destructive on background, card and secondary; success, warning and info on background; toast-foreground on toast.
  • Outlines: input on background, and ring on background and card.

A variation that misses one is not loaded, and Settings shows which pair failed and by how much.

For Tavora 0.23.9 and @tavora/sdk 0.3.3. Code under the MIT License. The Tavora name and logo are not covered by it.