Get started

Design token taxonomy template: define layers, scope, and change rules

A design token taxonomy records who controls a design decision, where it belongs, what it can change, and how it reaches real interfaces. It is broader than a naming convention but narrower than a complete implementation specification. The template below keeps that authority-to-consumer chain visible, including unresolved decisions that should not become tokens yet.

Updated October 2, 2026

Draw the boundary before naming anything

A taxonomy classifies design decisions. A naming convention expresses that classification in identifiers. A source format serializes the decisions, while a transformation converts them for a target. A project mapping connects an emitted identifier to local code. The rendered consumer is the actual button, card, page, or application state that uses that mapping. These records are related, but none proves the next link in the chain.

ArtifactIt decidesIt does not prove
TaxonomyLayer, purpose, scope, authority, and permitted relationshipsArchitecture and governanceThat an identifier was generated, adopted, or rendered correctly
Naming conventionIdentifier grammar, ordering, vocabulary, and separatorsSyntax for accepted decisionsThat the named decision belongs in the taxonomy
Source token formatHow token data and references are representedPortable source structureThat a transformation or consumer supports that structure
Generated artifactWhat a particular build emitted for a targetOutput from a named transformationThat the intended project received or uses the output
Project mappingHow an emitted value connects to local codeAdoption within a named project scopeThat every intended consumer uses the mapping
Rendered consumerWhat appeared under recorded conditionsA bounded runtime observationWhy it appeared or whether other consumers match
Keep each artifact within its evidence boundary.

The Design Systems Collective source covers hierarchy, aliases, modes, and component tokenization. VA.gov documents one applied vocabulary of primitive, semantic, and component types. Both are useful references, but neither is a universal answer. Your taxonomy still needs to state which authority, products, platforms, brands, modes, and consumers make a boundary valid for your system.

Freeze the current system first

Don't begin a revision with proposed names. First, preserve the existing route from authority to consumer. The EightShapes account moves from planning and audits of token paths and uses through proposal, specification, handoff, and implementation. A current-system intake protects the evidence you'll need during migration.

Current-system fieldWhat to recordFailure condition
Governing sourceDocument, repository, library, or authority that owns current intentRecord its exact location and authorityTwo sources claim final authority without a precedence rule
VersionRelease, revision, commit, or dated snapshot under reviewUse a value that another reviewer can retrieveThe source can change without the record showing what was assessed
Products and platformsNamed products and in-scope platformsList web, mobile, design libraries, documentation, or other targets separatelyScope is described only as all products or digital
Brands and modesEvery in-scope brand, theme, mode, density, or other axisState unsupported and excluded axes tooAn axis is inferred from filenames rather than declared
Token pathsSource, alias chain, transformation, distribution target, and project entry pointPreserve current paths before proposing replacementsA value is visible but its origin cannot be traced
TransformationsTool or process, configuration version, input, and outputSeparate the operation from its artifactsA generated value has no reproducible production record
ConsumersNamed components, pages, packages, applications, and representative statesUse inspectable consumer namesConsumers are reduced to a vague label such as frontend
OwnersDecision, artifact, project, correction, and retest owners where they differName accountable roles rather than a broad audienceA failure can be found but nobody owns its correction
ExclusionsProducts, platforms, brands, modes, states, or categories outside the reviewGive the reason for each material exclusionReaders could assume excluded surfaces were assessed
Known exceptionsExisting deviations, owners, rationale, and review triggerDistinguish accepted exceptions from unexplained driftA local override is mistaken for the shared rule
Complete this intake for the system before opening individual decision records.

Copy the taxonomy decision record

Use one record for each decision whose authority, placement, or migration can be reviewed independently. Required means the review can't proceed without the field. Conditional means the field becomes required when that feature exists. Unresolved means an owner still needs to decide it. Not applicable means the team considered the field and excluded it for a recorded reason.

record_id: "[required: stable review identifier]"
record_version: "[required: revision of this record]"

governance:
  governing_source: "[required]"
  governing_source_version: "[required]"
  decision_owner: "[required]"
  approval_state: "[required: proposed | accepted | revised | blocked | superseded]"

scope:
  products: ["required: named products"]
  platforms: ["required: named platforms"]
  brands: ["conditional: named brands, or not applicable with reason"]
  modes: ["conditional: named modes, or not applicable with reason"]
  exclusions: ["required: explicit exclusions, may be empty"]

identity:
  current_identifier: "[conditional: required for an existing decision]"
  proposed_identifier: "[conditional: required for a new or renamed decision]"
  purpose: "[required: stable meaning in plain language]"
  value_type: "[required: color | dimension | fontFamily | number | ...]"
  layer: "[required: primitive | shared-semantic | component | exception | implementation-rule | unresolved]"
  namespace: "[conditional: project or platform namespace]"

reach:
  brand_scope: "[conditional: shared, named brands, or unresolved]"
  mode_scope: "[conditional: shared role with per-mode values, named modes, or unresolved]"
  component_reach: ["required: named components or none"]
  named_consumers: ["required: concrete components, pages, packages, or apps"]
  independent_change_scope: "[required: what may change and what must remain unaffected]"

relationships:
  alias_target: "[conditional: target, unresolved, or not applicable]"
  token_paths: ["required: known source and downstream paths"]
  generated_artifacts: ["conditional: named outputs and versions"]
  transformations: ["conditional: tool or process, configuration, input, output"]
  project_mappings: ["conditional: emitted identifier to local implementation"]

migration:
  migration_state: "[required: not-started | mapped | compatibility-active | adopted | retired | blocked]"
  considered_alternatives: ["required: candidates and rationale"]
  rejected_alternatives: ["required: rejected candidate and reason"]
  old_to_new_mapping: "[conditional]"
  temporary_compatibility: "[conditional: mechanism or not applicable with reason]"
  known_exceptions: ["required: exception, owner, reason, review trigger"]

evidence:
  evidence_state: "[required: missing | expected | generated | implemented | observed]"
  expected_result: "[required: falsifiable expectation for named consumers]"
  observed_result: "[required: pending until inspected, then record what was found]"
  observation_context: "[conditional: versions, mode, brand, state, viewport, content, method]"

ownership:
  implementation_owner: "[conditional]"
  correction_owner: "[required when unresolved or a failure is found]"
  retest_owner: "[required when observation is pending or correction is needed]"

disposition:
  decision: "[required: accept | revise | block | supersede]"
  rationale: "[required]"
  decided_by: "[required]"
  decided_at: "[required when disposition is final]"
Repository-ready taxonomy decision record. Replace the bracketed instructions rather than treating them as policy.

How to fill the fields without hiding uncertainty

Purpose should describe stable meaning, not appearance. Write "background for primary action surfaces" rather than "bright yellow." Independent change scope should state what may move together and what must remain unaffected. Named consumers should be inspectable, such as "checkout submit button, default and focus states," rather than "buttons." The record will remain useful even if your vocabulary differs from a published system.

  • Use unresolved when the answer affects placement and no authority has decided it. Don't fill the gap with the author's preference.
  • Use not applicable only after considering the field and recording why it doesn't apply. An empty cell isn't the same decision.
  • Record aliases as relationships between meanings. Don't add one merely to make a hierarchy look complete.
  • List artifacts separately from transformations. An artifact is an output; a transformation is the reproducible operation that produced it.
  • Write expected results before inspection, then record what you found even when it contradicts the proposal.
  • Assign correction and retest to named owners. The source owner may not own the project mapping or consumer verification.

Route each decision with six possible outcomes

Primitive, semantic, and component are useful categories, but the familiar three-tier model doesn't settle every case. Real systems also need deliberate exceptions, ordinary implementation rules, and unresolved decisions. Placement follows meaning and change authority, not the number of consumers alone.

OutcomeChoose it whenReject or defer it when
PrimitiveThe value is reusable raw material without contextual purposeAnother layer controls meaning and consumptionConsumers depend on its appearance as though that appearance were a stable purpose
Shared semanticA stable purpose is shared by named consumersThose consumers should change together across declared brand and mode scopeThey merely share today's value or one needs an independent lifecycle
ComponentA named component property has independent change authorityIts states, affected consumers, and protected consumers are definedThe proposed layer only repeats a shared role or has no plausible independent change
Approved exceptionA specific consumer must deviate and the authority accepts itThe record names its owner, rationale, and review triggerThe deviation is accidental or avoids an unresolved taxonomy decision
Ordinary implementation ruleThe decision governs selector behavior, responsive composition, content structure, or algorithmic layoutToken delivery would not make the rule portable or clearerThe decision is a reusable value or role that must travel through artifacts
UnresolvedMeaning, authority, alias target, scope, consumers, or evidence is insufficientAn owner and next decision are recordedEnough evidence already supports another outcome
Evaluate all tests together. No single answer determines placement.

The shortcut "shared by several components means semantic" is unsafe. Several components may use the same value by coincidence. Before creating a shared role, ask whether they share one meaning, one authority, and one intended change. A component token earns its layer only when the component owns an independent decision and the record names both affected and protected consumers.

Apply the matrix to boundary cases

Boundary caseRouting consequenceEvidence or failure condition
Mode-specific valuesKeep one semantic role when meaning stays stable and its value changes by modeRecord light and dark values separately under the declared mode scopeFail if a verified light value is silently assigned to dark mode
Brand variantsKeep one role when brands express the same purpose differentlySplit the role or approve an exception when meaning, contract, or authority changesFail if brand parity is inferred from a shared file rather than recorded
Status statesUse shared roles when success, warning, or destructive meaning travels across componentsUse component scope only for independently governed behaviorA matching color without shared meaning is insufficient
Interaction statesKeep hover, focus, disabled, and pressed behavior in the owning component contractAlias to shared roles where the underlying meaning is genuinely sharedDefer when global and component authority cannot be distinguished
Typography rolesTokenize reusable family, size, weight, line-height, or role decisionsKeep wrapping, truncation, and content-dependent behavior in implementation or guidanceDo not convert every text declaration into a taxonomy level
SpacingUse primitives for reusable dimensions and higher layers only for stable intent or independent authorityKeep one-off arrangements in implementationA repeated number alone does not establish semantic meaning
LayoutKeep composition, ordering, grids, and container behavior as implementation rulesTokenize only portable values that need distributionA breakpoint token does not specify responsive behavior
Component contractsUse component tokens for independently changeable visual propertiesKeep structure, variants, behavior, and content rules in code and documentationFail when a token name is expected to carry a complete behavioral contract
CSS-only rulesKeep selectors, pseudo-classes, media queries, inheritance, and calculations in CSSExtract only reusable values that need a token pathA literal inside CSS does not automatically need a token
Documentation-only guidanceKeep prohibitions, rationale, examples, and usage boundaries in governed documentationLink the guidance to relevant records and consumersDo not encode prose policy as a token or claim documentation proves adoption
These are routing consequences, not universal token names.

More layers don't resolve missing authority

If a proposed token has no stable meaning, named consumers, or owner, another alias won't make it safer. Mark the decision unresolved and assign an owner.

Record Ambient Sage v1 as bounded upstream intake

Ambient Sage v1 works as a source fixture because its public page identifies a versioned kit with 28 semantic roles in light and dark modes. It also provides six artifact families: DESIGN.md, DTCG tokens, CSS variables, Tailwind v3, Tailwind v4, and a shadcn registry. Those facts stop at the upstream boundary. They don't establish a receiving project's namespace, aliases, transformations, mappings, consumers, migration status, accessibility evidence, or runtime observations.

Token specimen · real values

Ambient Sage

Live render

Ambient Sage's actual tokens — the same values its exports use.

Color tokensSemantic roles with HEX / HSL / CMYK

Color tokens

Ambient Sage
light · HEX · HSL · CMYK

Core

#F3F4EF

background

H 72 · C0, 0, 2, 4

#1A1C17

foreground

H 84 · C7, 0, 18, 89

#E5E6E0

card

H 70 · C0, 0, 3, 10

#ECEEE8

muted

H 80 · C1, 0, 3, 7

#D8D9D2

border

H 68.57 · C0, 0, 3, 15

Brand

#FEE951

primary

H 52.72 · C0, 8, 68, 0

#1A1C17

primary-fg

H 84 · C7, 0, 18, 89

#E5E6E0

secondary

H 70 · C0, 0, 3, 10

#F7E464

accent

H 52.24 · C0, 8, 60, 3

#FEE951

ring

H 52.72 · C0, 8, 68, 0

Semantic

#C0392B

destructive

H 5.64 · C0, 70, 78, 25

#FFFFFF

destructive-fg

H 0 · C0, 0, 0, 0

#2D7238

success

H 129.57 · C61, 0, 51, 55

#C97D12

warning

H 35.08 · C0, 38, 91, 21

#545651

muted-fg

H 84 · C2, 0, 6, 66

Charts

#FEE951

chart-1

H 52.72 · C0, 8, 68, 0

#4A8FD4

chart-2

H 210 · C65, 33, 0, 17

#6BBF8A

chart-3

H 142.14 · C44, 0, 28, 25

#E07498

chart-4

H 340 · C0, 48, 32, 12

#E8A24B

chart-5

H 33.25 · C0, 30, 68, 9

Ambient Sage v1 shown as upstream semantic color input. This specimen does not demonstrate project adoption or dark-mode verification.
Record areaAmbient Sage v1 intakeEvidence state
Governing source and versionPublic Ambient Sage kit pageVersion v1Verified upstream input
Semantic scope28 semantic rolesLight and dark values are documentedVerified upstream input
Available artifactsDESIGN.md, DTCG tokens, and CSS variablesTailwind v3, Tailwind v4, and shadcn registryVerified upstream input
Project namespace and aliasesNo receiving-project namespace suppliedNo project alias policy suppliedUnresolved
Transformations and mappingsNo receiving-project pipeline suppliedNo emitted-to-local mapping suppliedUnresolved
Named consumersNo receiving-project component suppliedNo page, state, or application suppliedUnresolved
Migration and compatibilityNo current project taxonomy suppliedNo compatibility requirement assessedUnresolved
Accessibility evidenceNo project-specific evaluation suppliedNo consumer conditions suppliedUnresolved
Runtime observationsNo project implementation performedNo rendered consumer inspectedUnresolved
Record verified intake and unresolved adoption separately.

Inspect the upstream roles before designing the mapping

Open the public Ambient Sage kit and inspect the source system. Adopt only the roles and artifacts that your taxonomy record can trace into named project consumers.

Trace one proposed row without pretending it ran

The fixture below is illustrative and unexecuted. Ambient Sage supplies the verified upstream light value and artifact availability. Every receiving-project identifier, alias, mapping, consumer, owner, expectation, and disposition remains explicitly proposed. The dark value is unresolved; it isn't inferred from the light value.

record_id: "example-surface-canvas-001"
execution_status: "illustrative and unexecuted"

governance:
  governing_source: "Ambient Sage public kit"
  governing_source_version: "v1"
  decision_owner: "proposed: design-system lead"
  approval_state: "proposed"

source_input:
  verified_light_value: "#f3f4ef"
  dark_value: "unresolved: inspect the v1 dark role before mapping"
  source_role: "proposed interpretation: main canvas surface"

identity:
  current_identifier: "not applicable: fictional new project mapping"
  proposed_identifier: "app.color.surface.canvas"
  purpose: "proposed: default application canvas background"
  value_type: "color"
  layer: "proposed: shared-semantic"
  namespace: "proposed: app"

relationships:
  alias_target: "proposed: exact Ambient Sage source path unresolved"
  emitted_artifact: "proposed: CSS variables artifact"
  project_mapping: "proposed: --app-surface-canvas maps to the inspected emitted role"
  named_consumer: "proposed: Settings page root, default state, light mode"
  component_reach: ["proposed: page canvas only"]
  protected_consumers: ["proposed: cards, dialogs, and navigation remain unchanged"]

migration:
  migration_state: "not-started"
  temporary_compatibility: "not applicable unless inventory finds an existing identifier"

evidence:
  expected_result: "Changing the mapped light canvas role changes the Settings page root while cards, dialogs, and navigation remain unchanged."
  observed_result: "pending: no artifact inspection, mapping, build, or rendered observation performed"
  accessibility_evidence: "unresolved: requires project-specific evaluation"

ownership:
  implementation_owner: "proposed: frontend platform owner"
  correction_owner: "proposed: owner of the first divergent layer"
  retest_owner: "proposed: Settings page maintainer"

disposition:
  decision: "block"
  rationale: "Do not accept until the exact source path, dark value, emitted identifier, mapping, and consumer observation are recorded."
Illustrative trace only. Proposed project details are not claims about Ambient Sage or a live implementation.

This row stays blocked even though its source is real and its expectation is plausible. That is intentional. Upstream approval, artifact availability, a proposed alias, project adoption, and a rendered observation are separate claims. None can stand in for the next.

Migrate the taxonomy as an evidence chain

A rename can affect design libraries, source data, transformations, packages, documentation, component code, and product surfaces. The EightShapes process connects audit, proposal, specification, handoff, and implementation. Use that breadth, but limit each recorded result to the layer you actually inspected.

  1. 1

    Inventory current uses

    Record every known source identifier, alias, transformation, artifact, project mapping, component, page, mode, brand, and local override. Name exclusions and gaps instead of assuming the inventory is complete.

  2. 2

    Record considered and rejected alternatives

    For every candidate structure, note its meaning, authority, change reach, migration consequence, and reason for retention or rejection. This preserves decisions that later contributors might otherwise reopen.

  3. 3

    Map old identifiers to proposed replacements

    Classify each relationship as one-to-one, one-to-many, many-to-one, removed without replacement, or unresolved. A textual rename is insufficient when meaning or scope changes.

  4. 4

    Identify affected artifacts and named consumers

    List every output and the concrete packages, components, pages, states, modes, and brands expected to change. Name the protected consumers that must remain unchanged.

  5. 5

    Define temporary compatibility

    If old and new identifiers must coexist, record whether an alias, adapter, duplicate output, or another bounded mechanism provides compatibility. Assign an owner and removal condition. Otherwise, mark it not applicable and record why.

  6. 6

    Write expected results before implementation

    State what should change, what should stay stable, and under which versions and conditions. Avoid subjective expectations such as looks correct.

  7. 7

    Generate and inspect artifacts

    Record what each transformation produced and whether the expected identifiers and mode values are present. Classify this as generated evidence, not project implementation.

  8. 8

    Adopt the mapping in named consumers

    Record the project version and exact mapping used by each representative consumer. Adoption establishes implementation only for that recorded scope.

  9. 9

    Observe and route divergence

    Inspect the named consumers under recorded modes, brands, states, content, and other relevant conditions. Record what happened, assign correction to the first divergent layer, and name a retest owner.

  10. 10

    Choose the final disposition

    Accept when the required evidence supports the stated scope. Revise a correctable proposal. Block when required authority, evidence, or ownership is missing. Supersede when an identified newer decision replaces the record.

Use states that describe evidence, not optimism

StateWhat it recordsWhat it does not prove
ProposedA candidate meaning, placement, name, scope, or migration planThe candidate is ready for reviewApproval, output, adoption, or runtime behavior
AcceptedThe named authority approved the decision for the stated scopeThe source decision is settled for that scopeThat an artifact was produced or a project adopted it
GeneratedA named transformation produced a recorded artifactArtifact production under a stated contextThat the artifact is correct for every target or used by a project
ImplementedA named project or consumer adopted the recorded mapping or contractProject adoption for the named version and scopeThat the rendered result matches the expectation
ObservedAn inspection recorded what happened under stated conditionsThe result may be a match, mismatch, or new findingSuccess or coverage outside the recorded conditions
RevisedThe decision or implementation changed in response to evidenceA new revision now requires downstream checksThat regeneration, adoption, or observation has occurred
BlockedA required decision, artifact, mapping, result, or owner prevents acceptanceThe blocking reason and owner are recordedThat the proposal must be abandoned rather than corrected
SupersededA newer identified record replaces this decisionHistorical authority remains traceableThat old consumers migrated or compatibility can be removed
DispositionA reviewer chose accept, revise, block, or supersedeThe rationale and evidence boundary are explicitAny broader claim than the stated scope supports
A record can satisfy one state and fail later in the chain.

Keep the record beside the source or change process your reviewers already use. A spreadsheet can work. A repository file, issue, or decision register is often easier to version when identifiers, transformations, and consumers change together. The storage format matters less than preserving the authority-to-consumer chain and refusing to treat blank fields as implied approval.

Complete one reused role before expanding the taxonomy

Choose the semantic role with the widest known reuse or the most disputed boundary. Complete its current-system intake, route it through the six-outcome matrix, name representative and protected consumers, and review the full record. Don't rename the rest of the taxonomy until that row has accepted authority, an explicit migration path, and observations recorded for its stated scope.

Sources

  • Reimagining a Token Taxonomy: The documented redesign process moves from planning and current-state audits through taxonomy decisions, specification, handoff, review, and implementation across design, code, and documentation.
  • Systematic Taxonomy in Design Tokens: The captured article discusses hierarchical naming, aliases, modes, component-specific tokens, and contextual token structures.
  • Design tokens - VA.gov Design System: The VA.gov Design System documents an applied taxonomy with primitive, semantic, and component token types, along with an explicit naming vocabulary.
  • Naming design tokens: The resource page collects separate guides, templates, workshops, and examples about token naming across platforms and brands.
  • Best Practices For Naming Design Tokens, Components And Variables: The article surveys naming conventions and examples for tokens, variables, components, and complex taxonomies.
  • An introduction to design tokens: The guide presents primitive, semantic, and component tokens as a common three-tier baseline while distinguishing design tokens from implementation variables.
  • Ambient Sage Design Kit: The public Ambient Sage v1 page documents 28 semantic tokens in light and dark modes and provides DESIGN.md, DTCG tokens, CSS variables, Tailwind v3, Tailwind v4, and shadcn registry artifacts.