I have been building an integration pipeline around Penpot’s token export and spent real time mapping exactly what comes out of the Export button in the Tokens panel. Sharing these findings in case it saves others debugging time.
What the docs say
@LauraKalbag’s recent post, A Practical Guide to the Design Tokens JSON Format, states:
“Penpot natively supports the design tokens standard JSON format by the Design Tokens Community Group”
It links to the DTCG 2025.10 specification and says you can import/export to any tool that supports “the design tokens format.”
What the export actually is
What Penpot exports is a Tokens Studio multi-set JSON file — the format used by the Tokens Studio plugin. This is a widely-used and well-documented format, but it is not what DTCG 2025.10 defines. The differences are significant enough to break integrations.
1. Outer structure — multi-set, not single-file
DTCG defines a single flat token file. Tokens Studio uses a multi-set envelope where each top-level key is a set name, alongside $themes and $metadata:
{
"Color/Palettes and Scales": { … },
"Color/Light Core": { … },
"$themes": […],
"$metadata": {
"tokenSetOrder": [...],
"activeThemes": [...]
}
}
DTCG has no concept of sets, themes, tokenSetOrder, or activeThemes.
2. Token type names
Several $type values differ:
Tokens Studio $type |
DTCG 2025.10 equivalent |
|---|---|
fontFamilies |
fontFamily |
fontSizes |
dimension |
spacing |
dimension |
borderRadius |
dimension |
borderWidth |
dimension |
fontWeights |
fontWeight |
3. Color values — hex strings vs structured objects
Tokens Studio: “$value”: “#0066cc”
DTCG 2025.10: “$value”: { “colorSpace”: “srgb”, “components”: [0, 0.4, 0.8] }
4. Dimension values — unit strings vs typed objects
Tokens Studio: “$value”: “16px”
DTCG 2025.10: “$value”: { “value”: 16, “unit”: “px” }
5. Numbers stored as JSON strings
Tokens Studio stores numeric values as JSON strings: “$value”: “16”. DTCG expects JSON numbers: “$value”: 16.
6. Math expressions and HSL colour functions
Tokens Studio supports expressions like “round({base} * pow({multiplier}, 2))” and “hsla({hue}, {saturation}%, {lightness}%, 1)” as raw string values. DTCG has no equivalent syntax.
Why this matters in practice
Any tool targeting strict DTCG 2025.10 — a style dictionary, a custom CSS generator, another design tool claiming DTCG compliance — will fail or silently drop values when given a Penpot export. Hex colours won’t parse, type names won’t match, the multi-set wrapper won’t be recognised.
The reverse is equally true: if you’re building something that needs to write tokens into Penpot, you need to produce Tokens Studio format, not DTCG. I built a shim library requiring 9 distinct transforms just to convert a single Penpot export into valid DTCG 2025.10 — that gives a reasonable sense of the gap.
Not a criticism — just clarity
Tokens Studio is a solid and widely-adopted format with strong tooling. This isn’t a knock on Penpot or the tokens work — the panel is well-built and the Tokens Studio integration is genuinely useful. The issue is that the documentation leads readers to expect DTCG compliance, which produces quiet, confusing failures when integrations don’t behave as expected.
Two things that would help the community:
-
Update the blog post and any in-app docs to accurately name the format as Tokens Studio, with a link to docs.tokens.studio for the format reference
-
If native DTCG 2025.10 export is on the roadmap, a note to that effect would set the right expectations for integrators
Happy to go deeper on any of the specific differences if useful.