Kimo
Docs
v1.0
Changeloggetkimo.design
Docs
v1.0
File format spec
§10

Variables and themes

On this page4 sections
  1. 10.1 Variables
  2. 10.2 Bindings and types
  3. 10.3 Themes
  4. 10.4 Resolution (normative)
Status
Stable (format version 1.0.0, frozen 2026-10). Backward compatible within 1.x (§16.4). Supersedes the draft v0.1, kept as a historical record; 0.1 files open through the 0.1 → 1.0 migration (§16.2).
Schema
https://getkimo.design/schema/kimo-1.0.json (JSON Schema draft 2020-12), generated into packages/core-schema/schema/kimo-1.0.schema.json. The 0.1 schema stays published at …/kimo-0.1.json (schema/kimo-0.1.schema.json, frozen).
Reference
@kimo/core-schema (packages/core-schema). Where this document and the implementation disagree, that is a bug in one of them; file an issue.
Plan of record
docs/teardown.md §10. Every place where this spec resolves an ambiguity in, or deviates from, that section is listed in §20.
License
MIT

10.1 Variables

JSON
"variables": {
"surface": { "type": "color", "value": [ { "value": "#FFFFFF", "when": { "mode": "light" } },
{ "value": { "$ref": "ink-900" }, "when": { "mode": "dark" } } ],
"group": "color.surface", "description": "Page background" }
}
FieldMeaning
typecolor, number, string, boolean; composite (feature tokens/composite): typography, shadow, dimension.
valueA plain value used under every theme, or a themed value: a non-empty array of entries { value, when?: record axis key → value }. An array is themed exactly when every element is an object with a value member (shadow arrays and plain values never qualify).
descriptionFree text.
groupDotted group path for DTCG export (e.g. color.surface).
type
Meaning color, number, string, boolean; composite (feature tokens/composite): typography, shadow, dimension.
value
Meaning A plain value used under every theme, or a themed value: a non-empty array of entries { value, when?: record axis key → value }. An array is themed exactly when every element is an object with a value member (shadow arrays and plain values never qualify).
description
Meaning Free text.
group
Meaning Dotted group path for DTCG export (e.g. color.surface).

Plain values by type: color → Color; number → Num; string → string | Ref; boolean → boolean | Ref; typography → a TextStyle without typography, or Ref; shadow → a shadow Effect or an array of them, or Ref; dimension → { value: number, unit: "px" } (px only in 0.x and 1.x), or Ref. A value that is a binding is an alias; an alias MUST name a variable of the same type.

Keywords:
MUST
MUST NOT
SHOULD
MAY
set in small mono caps wherever they are normative

10.2 Bindings and types

A binding MUST name an existing variable (VARIABLE_MISSING); alias:name names a variable of an imported library, which is never copied into the consumer. The bound variable's type MUST fit the property:

PropertyAccepted variable types
fill, color, colors, stroke paint, gradient stop colorcolor
opacity, gap, crossGap, pad, radius, stroke width / t r b l, shadow x y blur spread, effect radius, w, h, text size weight lineHeight letterSpacing, icon weightnumber, dimension
visible, clipboolean
content, icon, fontstring
effectsshadow
typographytypography
args of a text / boolean propstring / boolean
script inputs, shader uniforms, enum options, enum target valueany
fill, color, colors, stroke paint, gradient stop color
Accepted variable types color
opacity, gap, crossGap, pad, radius, stroke width / t r b l, shadow x y blur spread, effect radius, w, h, text size weight lineHeight letterSpacing, icon weight
Accepted variable types number, dimension
visible, clip
Accepted variable types boolean
content, icon, font
Accepted variable types string
effects
Accepted variable types shadow
typography
Accepted variable types typography
args of a text / boolean prop
Accepted variable types string / boolean
script inputs, shader uniforms, enum options, enum target value
Accepted variable types any

10.3 Themes

themes declares axes, each with its values; the first value is the default. A node's theme pins axes for its subtree; keys are axis keys (alias:axis for a library's axis) and values MUST be declared values of that axis (THEME_AXIS_UNKNOWN, THEME_VALUE_UNKNOWN). The same applies to when keys and values.

10.4 Resolution (normative)

  1. Effective theme of a node. Start from the defaults: the first value of every local axis, and for every loaded imported library alias, the first value of each of its axes under the key alias:axis. Walk from the root to the node along its placement path (parent links, which include instance placement and at nodes), so instances inherit from where they sit. At each node with theme, overwrite only the named axes. For nodes inside an expanded instance the placement path is the expanded one (§9.8 rules 2 and 4).
  2. Library axes are namespaced alias:axis and default from the library.
  3. Variable value. A plain value applies under every theme. For a themed value, an entry matches when every axis named in its when equals the effective value of that axis; axes it does not name are ignored (partial when is allowed). Entries without when, or with when: {}, are fallbacks only and never candidates. Among matching entries the last one in list order wins (no specificity ranking).
  4. No candidate. Use the fallback entry — the last entry without when (or with when: {}) — if there is one, otherwise the first entry. In both cases emit the lint THEME_NO_MATCH(variable, effectiveTheme).
  5. Aliases resolve recursively with cycle detection: a cycle is the error VARIABLE_CYCLE.
  6. Library variables ({ "$ref": "alias:name" }) resolve inside the library: a when key axis of the library reads the consumer's effective value of alias:axis, or the library's default for that axis. Paste-without-import copies the variables, with a "use existing" / "add renamed" choice.