skip to content

For design tokens, how does an alias chain resolve to a value, and what problems do long or circular alias chains cause?

level: middleimportance: should knowfreq 38%

answer

  1. follow each hop
  2. stop at an explicit value
  3. a loop has no value
  4. ripple and coincidental coupling

basics

~20 s

Resolution follows each alias to its target until it reaches a token holding an explicit value. A circular chain never reaches one and is an error; long chains are legal but make values hard to explain and changes ripple further than intended.

solid answer

~50 s

An alias is a token whose value is a reference to another token instead of a raw value. When a tool needs the actual value it follows the reference, and if the target is itself an alias it keeps going until it finds a token with an explicit value; the Design Tokens Community Group format allows chained aliases and says tools must follow them. A chain that loops back on itself never reaches a value, so the format says references must not be circular and tools must report the loop as an error. Long chains are legal but costly: explaining one component token's color may take four hops, a change low in the chain ripples further than its author expects, and tier boundaries blur. Most systems keep chains short and pointing one way: component to semantic to primitive.

code

json · 22 lines
json
{
  "color": {
    "blue": {
      "600": {
        "$type": "color",
        "$value": {
          "colorSpace": "srgb",
          "components": [0.11, 0.369, 0.839],
          "hex": "#1c5ed6"
        }
      }
    },
    "action": {
      "primary": { "$value": "{color.blue.600}" }
    }
  },
  "button": {
    "accept": {
      "background": { "$value": "{color.action.primary}" }
    }
  }
}

go deeper

for a junior

Know that an alias is a token pointing at another token, and that resolving it means following pointers until a real value appears.

for a middle

Walk a two-hop chain from component to semantic to primitive, explain why cycles are errors, and contrast an alias with a copied value.

for a senior

Diagnose chain problems in a live system: coincidental aliases coupling purposes, chains too deep to explain, and builds that must fail loudly on loops.

for a principal

Set the rules a whole system follows for chain direction and depth, and weigh the flexibility of chained semantics against the cost of explaining them to many teams.

## What an alias is A **design token** normally holds a value: a color, a dimension, a duration. An **alias** — the Design Tokens Community Group format treats "alias" and "reference" as synonyms — is a token whose value is instead a reference to another token. In that format the reference is written as the target token's path inside curly braces in the `$value` property, for example `{color.action.primary}`. A curly-brace reference must point at a complete token, not at a group of tokens. An alias does not need to declare its own type: its type is the resolved type of the token it points at. **Resolving** an alias means finding the actual value it stands for. The format says tools should preserve references and resolve them only when the actual value is needed, so a change to the target shows up wherever the alias is used. ## How a chain resolves Aliases may reference other aliases; the result is an **alias chain**. The format says tools must follow each reference until they reach a token with an explicit value. In a ride-hailing driver app: 1. `button.accept.background` holds `{color.action.primary}` — a component token aliasing a semantic token. 2. `color.action.primary` holds `{color.blue.600}` — a semantic token aliasing a primitive. 3. `color.blue.600` holds an explicit color value, the brand blue. Resolution stops here. So the accept-ride button's background resolves to the brand blue, two hops away. If the system re-points `color.action.primary` to a different primitive, the button's background resolves to the new color without anyone touching the button token. That is the point of aliasing: every token that references a changed alias, directly or through further hops, follows it. A **copy** behaves differently. Had someone set `button.accept.background` to the brand blue's value directly, it would look identical today and never follow a change again. Aliasing preserves the link; copying severs it. ## Circular references A chain can loop back on itself: token A aliases B, B aliases C, C aliases A. Following the references never reaches an explicit value. - The format states that references **must not** be circular; the value of every token in such a loop is unknown. - Tools must detect the loop and report it as an error affecting all tokens in the chain, rather than guessing a value. - Cycles rarely appear on purpose. They usually come from two people each re-pointing a token toward the other's, or from a lower-tier token being aliased "upward" to a token that already depends on it. ## Why long chains hurt Long chains are legal, but they carry costs that a short, directional chain avoids. | Problem | What you see | |---|---| | Hard to explain | "Why is this button this color?" takes four or five hops to answer | | Surprising ripple | Re-pointing a token low in the chain changes things its author never looked at | | Blurred tiers | Semantic tokens aliasing semantic tokens aliasing more semantic tokens hide which one is the real decision | | Coincidental coupling | Two purposes chained only because their values once matched start moving together | The coincidental case does the most damage. Suppose the surge-zone highlight token was aliased to `color.action.primary` because both were brand blue at the time. When a brand refresh re-points primary actions, the surge highlight changes too — on the map, in every city — without anyone deciding it should. ## Keeping chains healthy - **Point one way.** Component tokens alias semantic tokens; semantic tokens alias primitives. A lower tier does not alias a higher one. - **Prefer about one hop per tier.** A component token typically needs two hops to reach a value. More than that deserves a reason. - **Alias for meaning, not for matching values.** Chain two semantic tokens only when one should always follow the other — for example, a link color the brand wants to track the action color. - **Make the chain visible.** Documentation or tooling that shows each token's full resolution path turns debugging from archaeology into reading. - **Fail loudly.** A circular or dangling reference should stop the token build with a message naming the tokens involved, not produce an empty or stale value. How a chain is finally emitted for each platform — resolved to a plain value or kept as a live reference — is a separate build decision; the model of the chain is the same either way.

  • Should a semantic token ever alias another semantic token?
    Sometimes, when the relationship is genuinely one of meaning: a link color that should always follow the brand's action color can alias it, and the format allows such chains. Do it sparingly and on purpose. Aliasing two semantic tokens only because their values match today couples purposes that may need to diverge, and the next change to one silently moves the other.
  • How is an alias different from giving a token the same value as another token?
    An alias keeps a live link: when the target changes, the alias resolves to the new value. A token given the same value holds a snapshot that looks identical today and never follows a later change. Aliasing records that two tokens are related; copying records only that their values happened to match once.

saying these in an interview costs you the question

  • An alias can only point at a primitive, never at another alias.
  • A circular alias chain simply resolves to the last value it had.
  • Longer alias chains always make a token system more flexible.
  • Alias two tokens whenever their values happen to match.
  • Setting a token to another token's value is the same as aliasing it.