Blog

How References Work in BaseFrame

May 11, 2026 · BaseFrame

How semantic tokens stay connected to primitives — and how BaseFrame uses that to power theming, neutral swaps, and Figma sync.

Every token set BaseFrame generates has two distinct layers: primitives and semantics. The primitives hold raw values — hex colors, pixel sizes, font names. The semantics hold references to those primitives. Understanding how that connection works explains why changing one color in BaseFrame can cascade correctly across an entire design system.

What a reference looks like

In the W3C DTCG format, a reference is a $value that points to another token by path, wrapped in curly braces:

{
  "token": {
    "semantic": {
      "color": {
        "dark": {
          "background": {
            "solid": {
              "ghost": {
                "$value": "{token.primitive.color.eggplant.solid.900}",
                "$type": "color"
              }
            }
          }
        }
      }
    }
  }
}

{token.primitive.color.eggplant.solid.900} is not a hex code — it is an alias. Tools like Style Dictionary resolve these at build time, walking the token tree to find the referenced value and substituting it in the output. Figma's Tokens Studio does the same at sync time.

This means the semantic token doesn't contain a color — it points to one. If you change the primitive, the semantic follows automatically.

How BaseFrame builds the reference structure

When you upload a brand image, BaseFrame runs buildTokens() in src/lib/buildTokens.ts. The process starts by loading reference/tokens.json — a fully structured template that defines the complete semantic layer, but with all its $value fields already written as references to token.primitive.color.* paths.

BaseFrame then stamps your brand colors into the primitive layer:

{
  "token": {
    "primitive": {
      "color": {
        "brand": {
          "solid": {
            "500": { "$value": "#2563eb", "$type": "color" }
          }
        }
      }
    }
  }
}

The semantic layer is left untouched. It was already written to point at {token.primitive.color.brand.solid.500} — so now it automatically resolves to #2563eb. No rewriting of semantic tokens is necessary.

The neutral swap

One place where references are actively rewritten at runtime is the neutral tone selector. The reference file uses eggplant as the default neutral palette throughout all semantic tokens. When you pick a different neutral tone — say, Slate — BaseFrame finds every reference to {token.primitive.color.eggplant.*} in the semantic layer and replaces it with {token.primitive.color.slate.*}:

const replaced = semanticStr.replace(
  /\{token\.primitive\.color\.eggplant\./g,
  `{token.primitive.color.${targetPalette}.`,
)

This is a string-level find-and-replace on the serialized JSON, before it is parsed back. The result is a token set where every neutral-role semantic token now points to your chosen palette, and the primitive layer contains both palettes so the references resolve correctly.

How Figma sees references

The Figma export (buildFigmaTokens.ts) converts the DTCG structure into Tokens Studio format. Tokens Studio uses the same {set/path} reference syntax, so BaseFrame translates each DTCG alias into its equivalent Tokens Studio alias:

{token.primitive.color.brand.solid.500}
→  {primitive/color.brand.500}

Tokens Studio treats these as live variable bindings inside Figma. When you apply the semantic theme, Figma's variable system resolves each alias to its primitive value — the same two-pass resolution that Style Dictionary performs in code.

The $themes block in the export tells Tokens Studio which token sets are active for each mode, so switching between light and dark in Figma applies the correct semantic layer without touching any primitive values.

Why the two-layer model matters

The practical consequence of reference-based design is that you never edit semantic tokens directly when you rebrand. You change the primitive — the hex, the scale, the neutral — and every semantic role that points to it updates automatically.

In BaseFrame's case, this means:

The reference file (reference/tokens.json) is the schema that makes this possible. It encodes the design decisions — which roles exist, which primitives they map to — separately from the actual color values. BaseFrame's job is to fill in the primitives; the references do the rest.