Skip to content

feat: W3C DTCG v2025.10 design tokens compliance - #67

Merged
alexey1312 merged 13 commits into
mainfrom
feat/w3c-tokens-v2
Feb 25, 2026
Merged

feat: W3C DTCG v2025.10 design tokens compliance#67
alexey1312 merged 13 commits into
mainfrom
feat/w3c-tokens-v2

Conversation

@alexey1312

Copy link
Copy Markdown
Collaborator

Description

  • Add W3C DTCG v2025.10 compliant color export format with color objects (colorSpace, components, alpha, hex) alongside legacy v1 hex strings
  • Implement token alias resolution with "{Group.Token}" W3C reference syntax and circular reference detection
  • Add dimension and number token types with Figma scope-based classification (e.g., WIDTH_HEIGHT → dimension, FONT_WEIGHT → number)
  • Add unified download tokens subcommand that exports colors, typography, dimensions, and numbers into a single W3C JSON file
  • Build .tokens.json parser (TokensFileSource) supporting nested groups, $type inheritance, $root, $deprecated, and non-sRGB warnings
  • Integrate local tokens file source into PKL config via Common.TokensFile class — bypasses Figma API when tokensFile is set on a colors entry
  • Update documentation across CLAUDE.md, DocC, and README

Additional notes

  • 57 tasks across 3 phases: export compliance, token type expansion, and .tokens.json import
  • All 2306 tests passing
  • --w3c-version flag selects v1 (legacy) or v2025 (default) format
  • tokensFile source enables use without FIGMA_PERSONAL_TOKEN for teams using Tokens Studio or similar tools

alexey1312 and others added 8 commits February 25, 2026 10:48
…export

Refactor W3CTokensExporter to support v2025 and v1 (legacy) versions:
- Color $value uses structured color objects (colorSpace, components, alpha, hex)
- Multi-mode colors use $extensions.com.exfig.modes
- Assets use $extensions.com.exfig.assetUrl instead of invented $type: "asset"
- Typography decomposed into sub-tokens (fontFamily, fontSize, lineHeight, letterSpacing)
- Add --w3c-version v1|v2025 flag (default: v2025) to all download commands
- Add ColorTokenMetadata for Figma variableId/fileId in $extensions
- V1 preserves all legacy behavior for backward compatibility

Implements tasks 1.1-1.7, 2.1-2.5, 4.1-4.3, 6.1-6.7 from w3c-tokens-v2 change.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extend ColorsVariablesLoader to propagate alias paths, descriptions,
and metadata. Implement "{Group.Token}" W3C alias syntax in color
export with stable mode ordering and per-mode alias resolution.
Refactor exportColorsV2025 to extract helper methods.

Tasks: 3.1-3.5

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ping

Create NumberVariablesLoader to load FLOAT variables from Figma and
classify them as dimension or number based on variable scopes.
Add exportDimensions() and exportNumbers() to W3CTokensExporter.
Add resolvedType and scopes fields to VariableValue model.

Tasks: 5.1-5.6

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create DownloadTokens command that exports colors, typography,
dimensions, and numbers into a single W3C JSON file with deep-merge.
Add integration test for unified token output.

Tasks: 7.1-7.3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TokensFileSource parses W3C Design Token Community Group JSON files
with nested group parsing, $type inheritance, alias resolution with
circular reference detection, $root/$deprecated support, non-sRGB
color space warnings, and model mapping to ExFigCore types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…(tasks 9.1-9.6)

Add Common.TokensFile PKL class with path and groupFilter fields.
When tokensFile is set on a colors entry, the pipeline reads from
a local .tokens.json file instead of Figma API. Includes codegen,
bridging, validation, and integration tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move completed change to archive, sync delta specs
(design-tokens-export, tokens-file-source) to main specs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update CLAUDE.md files, DocC (Usage, Configuration, ExFig), and
README with new download tokens command, TokensFile source,
W3C v2025 format, NumberToken type, and local .tokens.json import.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @alexey1312, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the design token export capabilities by aligning with the latest W3C DTCG v2025.10 specification. It introduces a more structured and compliant output format for colors, supports advanced token alias resolution, and expands token types to include dimensions and numbers. A new unified command simplifies the export process, and a local file parser allows for offline workflows, reducing reliance on the Figma API. These changes provide greater flexibility and adherence to modern design token standards.

Highlights

  • W3C DTCG v2025.10 Compliance: Implemented W3C Design Tokens Community Group v2025.10 compliant color export format, now using color objects (colorSpace, components, alpha, hex) instead of legacy hex strings. Multi-mode colors are now represented using an $extensions.com.exfig.modes object.
  • Token Alias Resolution: Added support for W3C reference syntax "{Group.Token}" for token alias resolution, including detection of circular references to prevent infinite loops during parsing.
  • Dimension and Number Token Types: Introduced new dimension and number token types, classified based on Figma variable scopes (e.g., WIDTH_HEIGHT for dimension, FONT_WEIGHT for number), enhancing the granularity of exported design tokens.
  • Unified download tokens Subcommand: A new unified download tokens subcommand has been added, allowing the export of colors, typography, dimensions, and numbers into a single W3C JSON file.
  • Local .tokens.json File Parser: Developed a robust .tokens.json parser (TokensFileSource) that supports nested groups, $type inheritance, $root tokens, $deprecated flags, and provides warnings for non-sRGB colors.
  • PKL Configuration Integration: Integrated the local tokens file source into the PKL configuration via a new Common.TokensFile class, enabling the bypass of the Figma API when a tokensFile is specified for color entries.
  • Documentation Updates: Updated documentation across CLAUDE.md, DocC, and README to reflect the new features, commands, and configuration options.
Changelog
  • CLAUDE.md
    • Updated CLI command examples to include the new download tokens subcommand.
    • Adjusted the module count in the architecture section from twelve to fourteen.
    • Added an alternative data flow for tokens, indicating local .tokens.json file processing.
  • README.md
    • Added a new feature entry for local .tokens.json file import.
    • Updated the description of W3C Design Tokens export to specify DTCG v2025 format and unified JSON export.
    • Included an example for the new exfig download tokens command.
    • Added information about the --w3c-version flag and tokensFile support for colors.
  • Sources/ExFigCLI/CLAUDE.md
    • Updated the exfig download subcommand options to include tokens.
    • Added new modules (TokensFileSource.swift, W3CTokensExporter.swift, NumberVariablesLoader.swift, DownloadTokens.swift) to the architecture table.
  • Sources/ExFigCLI/Context/ColorsExportContextImpl.swift
    • Modified loadColors to conditionally load colors from a local tokens file using TokensFileSource or fall back to Figma.
    • Introduced loadColorsFromTokensFile and loadColorsFromFigma private methods to encapsulate loading logic.
  • Sources/ExFigCLI/ExFig.docc/Configuration.md
    • Added a new section documenting the 'Tokens File Source' configuration for PKL, including an example for loading colors from a local .tokens.json file.
  • Sources/ExFigCLI/ExFig.docc/ExFig.md
    • Added 'Design Tokens' to the list of features, detailing the export of unified W3C DTCG design tokens.
  • Sources/ExFigCLI/ExFig.docc/Usage.md
    • Added an example for the new exfig download tokens command.
    • Updated the download subcommand table to include tokens and its description.
    • Added the --w3c-version option to the download options table.
  • Sources/ExFigCLI/Input/TokensFileSource.swift
    • Added a new file implementing TokensFileSource, a parser for W3C DTCG .tokens.json files.
    • Defined TokensFileError, ParsedToken, and ParsedTokenValue structs for token representation.
    • Implemented parsing logic for nested groups, token values (color, dimension, number, typography, fontFamily), and special fields like $root and $deprecated.
    • Included alias resolution with circular reference detection and model mapping functions to convert parsed tokens to ExFigCore models.
  • Sources/ExFigCLI/Loaders/Colors/ColorsVariablesLoader.swift
    • Modified LoadResult to include aliases, descriptions, and metadata for color tokens.
    • Updated load and mapVariablesToColorOutput functions to collect and propagate these new metadata fields.
    • Adjusted handleColorMode to record alias paths for referenced variables.
  • Sources/ExFigCLI/Loaders/NumberVariablesLoader.swift
    • Added a new file implementing NumberVariablesLoader to load FLOAT variables from Figma.
    • Implemented logic to classify numeric variables as dimension or number based on Figma scopes.
    • Included functions to resolve variable aliases for numeric values and map Figma scopes to W3C token types.
  • Sources/ExFigCLI/Output/DownloadExportHelpers.swift
    • Updated exportW3C functions for assets, colors, and typography to accept a w3cVersion parameter.
    • Modified exportW3C for colors to pass descriptions, metadata, and aliases to the exporter.
    • Added fileId parameter to AssetExportHelper.exportW3C.
  • Sources/ExFigCLI/Output/W3CTokensExporter.swift
    • Introduced W3CVersion enum to differentiate between v1 (legacy) and v2025 export formats.
    • Refactored colorToHex to produce 6-digit hex for v2025 and added colorToHexLegacy for v1.
    • Added colorToObject functions to convert RGBA to v2025.10 Color Module objects.
    • Implemented separate export logic for v1 and v2025 for colors, typography, and assets.
    • Added exportDimensions and exportNumbers methods for new token types.
    • Updated asset export to use $extensions.com.exfig.assetUrl instead of $type: "asset" for v2025.
    • Modified typography export to decompose into individual sub-tokens for v2025.
  • Sources/ExFigCLI/Resources/Schemas/Common.pkl
    • Added a new TokensFile class to define the structure for local .tokens.json file sources.
    • Added an optional tokensFile property to the VariablesSource class.
  • Sources/ExFigCLI/Subcommands/Download.swift
    • Added w3cVersion option to JSONExportOptions.
    • Included DownloadTokens.self in the list of available download subcommands.
    • Updated the call to ColorExportHelper.exportW3C to pass additional parameters for descriptions, metadata, aliases, and w3cVersion.
  • Sources/ExFigCLI/Subcommands/DownloadAll.swift
    • Updated calls to ColorExportHelper.exportW3C and TypographyExportHelper.exportW3C to include w3cVersion and new color-related parameters.
  • Sources/ExFigCLI/Subcommands/DownloadIcons.swift
    • Updated the call to AssetExportHelper.exportW3C to include fileId and w3cVersion.
  • Sources/ExFigCLI/Subcommands/DownloadImagesExport.swift
    • Updated the call to AssetExportHelper.exportW3C to include fileId and w3cVersion.
  • Sources/ExFigCLI/Subcommands/DownloadTokens.swift
    • Added a new file implementing the DownloadTokens subcommand for unified W3C JSON export.
    • Orchestrates fetching and exporting colors, typography, and number variables (dimensions and numbers) into a single output file.
    • Includes a mergeTokens static function for deep-merging token dictionaries.
  • Sources/ExFigCLI/Subcommands/DownloadTypography.swift
    • Updated the call to TypographyExportHelper.exportW3C to include w3cVersion.
  • Sources/ExFigCLI/TerminalUI/ExFigWarning.swift
    • Added a new warning type: unresolvedNumberAlias.
  • Sources/ExFigCLI/TerminalUI/ExFigWarningFormatter.swift
    • Updated formatCompact to handle the new unresolvedNumberAlias warning.
  • Sources/ExFigConfig/CLAUDE.md
    • Updated the ExFigConfig architecture documentation to include Common.TokensFile and note the new tokensFile field in Common_VariablesSource.
    • Revised the purpose description for Common_VariablesSource.validatedColorsSourceInput() to reflect its new behavior with tokensFile.
  • Sources/ExFigConfig/Generated/Android.pkl.swift
    • Added tokensFile: Common.TokensFile? property to Android.ColorsEntry and its initializer.
  • Sources/ExFigConfig/Generated/Common.pkl.swift
    • Added tokensFile: Common.TokensFile? property to Common_VariablesSource protocol and VariablesSourceImpl struct.
    • Added TokensFile struct definition.
  • Sources/ExFigConfig/Generated/Flutter.pkl.swift
    • Added tokensFile: Common.TokensFile? property to Flutter.ColorsEntry and its initializer.
  • Sources/ExFigConfig/Generated/Web.pkl.swift
    • Added tokensFile: Common.TokensFile? property to Web.ColorsEntry and its initializer.
  • Sources/ExFigConfig/Generated/iOS.pkl.swift
    • Added tokensFile: Common.TokensFile? property to iOS.ColorsEntry and its initializer.
  • Sources/ExFigConfig/VariablesSourceValidation.swift
    • Modified validatedColorsSourceInput to check for tokensFile and, if present, bypass Figma API validation, returning a local-file source input.
    • Ensured that if tokensFile is not present, the function falls back to requiring Figma-specific fields.
  • Sources/ExFigCore/CLAUDE.md
    • Added a section detailing local tokens file support for ColorsSourceInput.
    • Included NumberToken in the domain models table.
  • Sources/ExFigCore/Protocol/ExportContext.swift
    • Added tokensFilePath and tokensFileGroupFilter properties to ColorsSourceInput.
    • Introduced an isLocalTokensFile computed property to ColorsSourceInput.
    • Updated the initializer for ColorsSourceInput to include the new tokens file path and group filter parameters.
  • Sources/FigmaAPI/Model/Variables.swift
    • Added resolvedType and scopes properties to VariableValue to capture more detailed Figma variable metadata.
  • Tests/ExFigTests/Input/EnumBridgingTests.swift
    • Updated initializers for iOS.ColorsEntry, Android.ColorsEntry, Flutter.ColorsEntry, and Web.ColorsEntry to include the new tokensFile parameter.
    • Added new test cases (testTokensFileSourceBypassesFigmaValidation, testTokensFileSourceWithGroupFilter, testWithoutTokensFileFallsBackToFigmaValidation) to validate the TokensFile source integration.
  • Tests/ExFigTests/Input/TokensFileSourceTests.swift
    • Added a new test file with comprehensive unit tests for TokensFileSource.
    • Tests cover parsing flat and nested color tokens, dimension, number, and typography tokens.
    • Includes tests for alias resolution, circular alias detection, $root tokens, $deprecated fields, non-sRGB color warnings, font weight string mapping, and various validation scenarios.
    • Contains integration tests for exporting colors from a local .tokens.json file with and without group filters.
  • Tests/ExFigTests/Output/W3CTokensExporterTests.swift
    • Updated color hex conversion tests to reflect the new v2025 6-digit hex format and added legacy v1 hex tests.
    • Added tests for the new colorToObject function for v2025 color module objects.
    • Revised color export tests for v2025 to verify color objects in $value and $extensions.com.exfig.modes.
    • Added tests for color export with alpha, descriptions, and Figma metadata.
    • Included tests for alias handling in v2025 and its disabled behavior in v1.
    • Updated typography export tests for v2025 to verify composite and decomposed sub-tokens, and added v1 typography tests.
    • Updated asset export tests for v2025 to verify the use of $extensions.com.exfig.assetUrl instead of $type: "asset", and added v1 asset tests.
    • Added tests for dimension and number token export, verifying their $type and $value formats.
    • Included tests for scope-to-token-type mapping in NumberVariablesLoader.
    • Added a unified token export integration test to verify merging of all token types.
  • openspec/changes/archive/2026-02-25-w3c-tokens-v2/.openspec.yaml
    • Renamed from openspec/changes/w3c-tokens-v2/.openspec.yaml.
  • openspec/changes/archive/2026-02-25-w3c-tokens-v2/design.md
    • Renamed from openspec/changes/w3c-tokens-v2/design.md.
  • openspec/changes/archive/2026-02-25-w3c-tokens-v2/proposal.md
    • Renamed from openspec/changes/w3c-tokens-v2/proposal.md.
  • openspec/changes/archive/2026-02-25-w3c-tokens-v2/specs/design-tokens-export/spec.md
    • Renamed from openspec/changes/w3c-tokens-v2/specs/design-tokens-export/spec.md.
  • openspec/changes/archive/2026-02-25-w3c-tokens-v2/specs/tokens-file-source/spec.md
    • Renamed from openspec/changes/w3c-tokens-v2/specs/tokens-file-source/spec.md.
  • openspec/changes/archive/2026-02-25-w3c-tokens-v2/tasks.md
    • Added a new file detailing the completed tasks for W3C DTCG v2025.10 compliance, token extensions, aliases, dimension/number types, typography decomposition, unified download, TokensFileSource parser, and PKL integration.
  • openspec/specs/design-tokens-export/spec.md
    • Added a new file outlining the detailed requirements and scenarios for the Design Tokens Export Capability, covering W3C DTCG v2025.10 color format, token extensions, descriptions, aliases, invented types, dimension/number tokens, and typography decomposition.
  • openspec/specs/tokens-file-source/spec.md
    • Added a new file outlining the detailed requirements and scenarios for the Tokens File Source Capability, covering parsing W3C DTCG format, group features, PKL config integration, offline workflow, token type mapping, alias resolution, and validation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an impressive and substantial feature addition that brings the tool's design token support up to the latest W3C standard. The changes are well-structured across multiple phases, including export compliance, token type expansion, and a new local file import capability. The introduction of the unified download tokens command and the TokensFileSource parser are great additions that significantly enhance the tool's flexibility and enable offline workflows.
The test coverage for the new functionality, especially for the token parser and the new exporter logic, is excellent and very thorough. The documentation updates across README.md, CLAUDE.md, and DocC are also clear and comprehensive.
I have one main piece of feedback regarding the implementation of the new .tokens.json parser, which deviates from the repository's established conventions for JSON processing. Please see the specific comment for details.

Comment thread Sources/ExFigCLI/Input/TokensFileSource.swift
alexey1312 and others added 5 commits February 25, 2026 12:04
Addresses PR #67 review feedback: TokensFileSource now uses the project's
JSONCodec/YYJSON for parsing instead of Foundation's JSONSerialization.

- Add JSONValue/JSONObject/JSONArray typealiases and parseValue(from:) to
  JSONCodec for untyped DOM access without direct YYJSON imports
- Refactor TokensFileSource to use JSONValue subscripts (.string, .number,
  .array, .object) instead of [String: Any] casts
- Change ParsedToken.extensions from [String: Any]? to JSONValue?
- Simplify ParsedTokenValue.unknown by removing unused Any payload

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Critical: guard `sortedModeColors.first` instead of force subscript [0],
add summary warning for .unknown tokens after alias resolution with
assert(isResolved) precondition on all mapping methods.

Error handling: add depth limit (10) to ColorsVariablesLoader.handleColorMode
to prevent stack overflow on circular aliases, warn about skipped sections
in `download tokens` with error on empty output, distinguish depth-exceeded
from unresolved in NumberVariablesLoader via ResolveResult enum, warn on
non-string fontFamily entries and unexpected $deprecated types, warn when
local tokens file ignores mode config.

Type safety: make NumberToken.variableId/fileId optional (String?),
conditionally emit $extensions in W3C exporter, make insertToken private.

Docs: fix $extends claim (not implemented, now emits warning), fix
colorToHex doc RGBA→RGB, remove 13 Task X.Y references, fix --output
required→optional in DocC, fix NumberToken location in CLAUDE.md,
fix MEMORY.md scope classification.

Code quality: simplify scopesToTokenType, remove basePath alias,
replace test deepMerge helper with production mergeTokens, add
swiftlint:enable file_length to W3CTokensExporter.
Config-free CLI for working with W3C DTCG .tokens.json files directly,
without PKL config or Figma token. Includes `info` (inspect) and
`convert` (filter/re-export) subcommands.

- Add `exfig tokens info` with human-readable and --json output
- Add `exfig tokens convert` with --group, --type, --w3c-version, --compact
- Add filtering/statistics methods to TokensFileSource
- Move mergeTokens to W3CTokensExporter as shared static method
- Update README with new tokens commands
- Replace JSONSerialization with JSONCodec via Codable TokensInfoReport
- Use FileHandle.standardOutput instead of print() for data output
- Rename resolvedAliasCount → aliasCount for accuracy
- Extract W3CTokensExporter.exportAll(from:) to eliminate duplication
- Add stable secondary sort by name in topLevelGroups()
- Add combined group+type filter test
@alexey1312
alexey1312 merged commit ec4151a into main Feb 25, 2026
3 checks passed
@alexey1312
alexey1312 deleted the feat/w3c-tokens-v2 branch February 25, 2026 14:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant