Skip to content

Schema convention: shorthand for $extensions namespaces (readability vs. DTCG purity) #88

@nathanacurtis

Description

@nathanacurtis

Problem

The schema uses DTCG-style $extensions to carry platform-specific provenance — e.g. on Props, TokenReference, and (per ADR-044, in progress) SlotBinding. The pattern is pure and namespace-clean, but the nesting hurts authoring and reading. ADR-044 review surfaced this concretely:

children:
  $binding: "#/props/items"
  $extensions:
    com.figma:
      default: defaultItems

Five lines, three indent levels, for one piece of data. The same shape recurs everywhere $extensions appears today and in any future platform-specific field.

This issue is to decide a schema-wide shorthand convention before more $extensions sites land. ADR-044 (and any other in-flight $extensions work) would then update mechanically.

Status quo (no change)

Keep $extensions['<reverse-dns>'] as the canonical form everywhere. Verbose but unambiguous and aligned with DTCG.

$extensions:
  com.figma:
    default: defaultItems

Option 1 — $ns:field colon-prefixed key (XML-namespace style)

children:
  $binding: "#/props/items"
  $figma:default: defaultItems

Pros: one line per fact; namespace visible in the key; matches the schema-control-key convention ($binding, $extensions).

Cons: colons in keys need quoting in some YAML contexts; reads as one token, not "namespace + field"; doesn't group multi-field cases — $figma:default and $figma:other lose their visual grouping; tooling that treats keys as identifiers (codegen, type generation) needs special handling.

Option 2 — Blessed top-level namespace key ($figma$extensions['com.figma'])

children:
  $binding: "#/props/items"
  $figma:
    default: defaultItems

Pros: 3 lines instead of 5; preserves namespace grouping when multiple fields exist; reads naturally; $figma matches $binding as a schema-control key; one canonical surface (we'd make $figma canonical and drop $extensions['com.figma'] for blessed platforms).

Cons: introduces a "blessed namespace" registry — what about $sketch, $penpot, $framer?; each new blessed namespace needs an ADR; long-tail/unknown platforms still need a fallback (probably $extensions['<reverse-dns>']), so two surfaces coexist.

Option 3 — Reverse-DNS flat key (DTCG-adjacent flat form)

children:
  $binding: "#/props/items"
  $com.figma.default: defaultItems

Pros: one line; namespace fully preserved and inspectable; no registry decision needed; works for any platform without blessing.

Cons: dots-in-keys are awkward across tooling (JSON Pointer collisions, GraphQL identifier rules, some YAML parsers); visually busy; doesn't group multi-field cases — every field repeats the full namespace prefix.

Discussion seeds

  • Is platform diversity expected to grow (multiple design tools)? Argues for Option 1 or 3 (no registry overhead).
  • Is Figma overwhelmingly dominant? Argues for Option 2 (one good shorthand for the common case, long form for the rare one).
  • Do consumers branch on extension keys structurally (treat $extensions as one bag) or by platform (look up com.figma directly)? Affects how painful "two surfaces" actually is.
  • Constitution §I requires type ↔ schema parity — whichever option is chosen needs a clean way to express it in both types/ and schema/ JSON Schema definitions.

Suggested next step

Open an ADR in adr/ proposing a convention (likely Option 2 with Figma as the first blessed namespace, but worth weighing against the others). Update existing $extensions sites and ADR-044's draft to match once accepted.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions