In a design token build, when should a platform output resolve aliases to literal values, and when should it preserve the references between tokens?
answer
- final values or live links
- who overrides at runtime
- every referenced token must ship
- per-output decision
- self-contained versus relational
basics
~20 sResolve aliases when a platform only needs final values and nothing overrides tokens after the build; preserve references when outputs are overridden at runtime, so changing one underlying token updates every token that points at it.
solid answer
~50 s**Resolving** writes the final literal into every output token. Each generated token then stands alone, needs no runtime lookup and works on any platform, but the relationship is gone: overriding an underlying token, for a customer's brand or a theme, means rebuilding. **Preserving** emits output tokens that point at other output tokens - a web style variable whose value is another variable, a native constant defined as another constant - so overriding one underlying token cascades at runtime, and the output still documents how tokens relate. The costs are that every referenced token must also be emitted, so internal palette tokens cannot be filtered out, definitions must be ordered validly, and lookups happen at runtime. Many systems preserve references in the web output, where runtime overrides are common, and resolve for native or design-editor outputs, but it is a per-output choice.
code
pseudocode · 12 linesfor each output in build.outputs:
for each token in source.tokens:
if token.value is a reference:
if output.policy == RESOLVE:
emit(token, resolveChain(token))
else: # PRESERVE
target = token.value.target
if target not in output.emittedTokens:
fail("preserved reference to filtered token", token, target)
emit(token, referenceTo(target))
else:
emit(token, convert(token.value, output.platform))go deeper
Recall the two options: write final values into every output token, or keep output tokens pointing at each other.
Explain the trade-off: self-contained, filterable, lookup-free outputs versus runtime overrides that cascade and relationships that stay visible.
Show how you choose per output from real override needs, and how the build must reject preserved references to filtered tokens.
Relate the policy to the product's customisation model: how much runtime overriding the business needs, and what it costs every platform.
## What an alias becomes in an output In a token source, an **alias** (or reference) is a token whose value points at another token instead of holding a literal. When a **token build** writes a platform output, it has to decide what that alias becomes: - a **resolved** literal - the build follows the reference chain to the final value and writes that value; or - a **preserved** reference - the build writes an output token that refers to another output token, in whatever form the platform supports. Why a source uses aliases, and how many layers it should have, is a design question about tiers. The build question is only what each output should contain. ## Resolving - **Self-contained.** Every generated token reads alone; nothing else needs to be loaded for it to work. - **No runtime cost.** Values are final, so no lookup happens at render time. - **Portable.** Works for any target, including formats with no way to express a reference. - **Filterable.** Internal tokens that consumers should not use directly can be dropped from the output, because nothing points at them any more. - **Cost:** the relationship is lost. If a customer or a theme needs to change the underlying value at runtime, every dependent token must be changed individually, or the build rerun. ## Preserving - **Relational.** Overriding one underlying token at runtime updates everything that references it. - **Self-documenting.** Reading the output shows that the overdue-status color *is* the palette's red, not merely equal to it. - **Smaller overrides.** A white-label customer can change a handful of underlying tokens rather than hundreds of role tokens. - **Cost:** every referenced token must be present in the output, so internal tokens cannot be filtered out; definitions must appear in an order the platform accepts; and each use involves a lookup at runtime. ## Side by side | Concern | Resolve | Preserve | |---|---|---| | Runtime overrides of an underlying token | need a rebuild | cascade automatically | | Output reads alone | yes | no - needs its targets | | Filtering out internal tokens | safe | breaks references | | Runtime lookup cost | none | small, per use | | Target must support references | no | yes | ## Choosing per output The decision is made **per output**, not once for the system: 1. **Web output** is often preserved, because runtime overrides - a customer's brand, a theme applied to one region of a page - are common there and style variables can reference each other. How those overrides are applied and scoped is a theming topic. 2. **Native outputs** are often resolved, because values are compiled into the app and runtime overrides are rarer or handled by swapping a whole set of values. 3. **Design-editor outputs** may preserve references so designers see and keep the relationships the source defines, if the editor's model supports them. ## Pitfalls - **Dangling references.** Preserving references while filtering internal tokens out of the output leaves tokens that point at nothing; the build should refuse that combination. - **Partial resolution.** Resolving some hops of a chain and preserving others produces outputs whose behaviour under override is hard to predict; choose one policy per output. - **Composite values.** A shadow or typography token whose parts reference other tokens needs the same policy applied to each part. - **Resolving too early.** A build that resolves before applying platform transforms may convert a value twice, or not at all. ## An accounting example A small-business accounting product is sold to accountancy firms, who put their own brand color on the client portal. The web output preserves references, so the portal's invoice-status and action tokens all point at a handful of underlying brand tokens, and each firm overrides only those at runtime. The native apps are not rebranded per firm, so their outputs are resolved: every generated constant holds a final value, the internal palette is filtered out, and nothing looks up anything at render time.
- What breaks if a token build preserves references but filters internal palette tokens out of the web output?Role tokens in the output still point at palette tokens that were never emitted, so their values are undefined at runtime and screens render fallbacks or nothing. The build should detect a preserved reference to a filtered token and fail, or the output should switch to resolving those references.
- Why is resolution usually a per-output decision rather than one setting for the whole design token build?Platforms differ in what they can express and in whether anything overrides values after the build. The web often needs runtime overrides and supports references between variables; compiled native apps often do not. A single setting would force either needless runtime lookups on native or lost overrides on the web.
saying these in an interview costs you the question
- Resolved outputs still update when an underlying token is overridden at runtime.
- Internal tokens can always be filtered out, whatever the resolution policy.
- One resolution policy must apply to every platform output.
- Preserving references has no runtime cost at all.
- Resolving some hops of a chain and preserving others is harmless.