[Infra] The Figma library's six theme collections declare theme modes but hold no variables
- Dominant language
- TypeScript
- Stars
- 13.2k
- Forks
- 1.1k
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 669
Description
## Problem
`@astryxdesign/core` ships seven themes, each with a generated, `@scope`d 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** | ` Light` / ` Dark`, or `` | **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 summing `variableIds` counts the same
166 seven times over. We initially misread this as "themes are modes with values";
it is not.
- Nothing is unpublished. `hiddenFromPublishing` is `false` on every collection and
every variable, so this is genuinely empty rather than staged-but-not-shared. From
a subscribing file, `getVariablesInLibraryCollectionAsync` returns 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:
1. 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".
2. The generator already exists on the code side. `astryx theme build` turns a
`defineTheme()` config into a stylesheet plus a `__built` token 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).
Contributor guide
Research direction
Start with the `astryx theme build` entry point and inspect the generated scoped `theme.css` and `__built` token module. Compare their resolved tokens with the Figma library's empty theme collections through the Figma plugin API. Done requires a decided direction: populate the theme modes from generated tokens, or remove or clearly label the empty shells.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- figma, typescript
- Domain
- design, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100