-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[Infra] The Figma library's six theme collections declare theme modes but hold no variables #5923
Description
Problem
@astryxdesign/core ships seven themes, each with a generated, @scoped stylesheet
(@astryxdesign/theme-chocolate/theme.css and so on). In the Figma library, those
themes have no values at all.
The library has 24 variable collections. Six of them own every variable; the other 18
own none. The 18 are named after the six shipped themes — Chocolate, Matcha, Gothic,
Butter, Y2K, Stone — one per themeable dimension (Color, Typography, Radius). Each
declares the right modes (Chocolate Light, Chocolate Dark, ...) and holds nothing
in them.
So a designer can select a theme mode in Figma and see no change, and there is no
path by which the code's themes reach the design tool.
Evidence
Read directly in Astryx Library (Community) (cYTWQpjWxbR30zwQgqlSmY) through the
Figma plugin API, read-only, on 2026年09月02日:
getLocalVariablesAsync() -> 166 distinct variables
getLocalVariableCollectionsAsync() -> 24 collections
sum of collection.variableIds -> 1048
Grouping every variable by its own variableCollectionId:
| collection | modes | variables owned |
|---|---|---|
| Color | Neutral Light, Neutral Dark |
108 |
| Typography | Neutral |
33 |
| Spacing | Default |
15 |
| Radius | Neutral |
6 |
| Size | Default |
3 |
| Border | Default |
1 |
| 18 theme collections | <Theme> Light / <Theme> Dark, or <Theme> |
0 each |
Two details worth stating precisely:
- The 1048 figure is double counting, not a larger set. The empty theme
collections list the base variables by id, so summingvariableIdscounts the same
166 seven times over. We initially misread this as "themes are modes with values";
it is not. - Nothing is unpublished.
hiddenFromPublishingisfalseon every collection and
every variable, so this is genuinely empty rather than staged-but-not-shared. From
a subscribing file,getVariablesInLibraryCollectionAsyncreturns zero for all 18.
What does work: the base Color collection carries both Neutral Light and
Neutral Dark, and all 108 colour variables have a value in each. Light/dark
round-trips cleanly. It is the six named themes that do not.
Why this may be intentional, and why it still seems worth raising
The Night Watch wiki is explicit that "code is king; Figma reflects released code,
never the reverse", and lists the token-generation workflow as undocumented. So the
gap may simply be un-implemented rather than broken. Two reasons to raise it anyway:
- The shells exist, with correct mode names. That reads as an intended feature
left half-built, and a designer encountering it cannot tell the difference between
"not implemented" and "broken". - The generator already exists on the code side.
astryx theme buildturns a
defineTheme()config into a stylesheet plus a__builttoken module; we ran it
on a four-line brand config and got 14 KB of scoped CSS. The same resolved token
set is what the Figma modes would need. Emitting mode values from the same source
looks tractable rather than speculative.
Proposed direction
- Have the theme build emit a machine-readable token dump per theme (it already
resolves every token), and let the Librarian write those into the matching mode. - Or, if theme parity in Figma is deliberately out of scope, remove the empty
shells or label them, so the library does not advertise modes that do nothing.
Offer
Happy to contribute the token-mapping side of this. We have measured the
Figma-name ↔ CSS-custom-property correspondence across all 166 variables and can
supply it as a table plus a checker — offered in #5922.
Environment
@astryxdesign/core@0.5.2 and all seven @astryxdesign/theme-*@0.5.2.
Figma Desktop, plugin API via the Figma Console MCP Desktop Bridge (no REST token).