Ogni esportazione di figmascope include tokens.json. È il ponte tra i valori visivi di Figma e le costanti tipizzate di cui ha bisogno il tuo codice. Questo articolo copre lo schema, come vengono nominati i token, cosa succede quando un file Figma non ha Variables, e dove il sistema di token presenta onestamente dei limiti.
Lo schema
La struttura di primo livello ha quattro sezioni:
{
"spacing": {
"spacing.4": { "$value": 4, "$type": "dimension" },
"spacing.8": { "$value": 8, "$type": "dimension" },
"spacing.12": { "$value": 12, "$type": "dimension" },
"spacing.16": { "$value": 16, "$type": "dimension" },
"spacing.24": { "$value": 24, "$type": "dimension" }
},
"radius": {
"radius.4": { "$value": 4, "$type": "dimension" },
"radius.8": { "$value": 8, "$type": "dimension" },
"radius.12": { "$value": 12, "$type": "dimension" }
},
"color": {
"color.7f5cfe": { "$value": "#7f5cfe", "$type": "color" },
"color.ffffff": { "$value": "#ffffff", "$type": "color" },
"color.1a1a2e": { "$value": "#1a1a2e", "$type": "color" }
},
"typography": {}
}
Il formato è W3C Design Tokens Community Group-ish: ogni token è un oggetto con $value e $type. Non è una implementazione stretta di W3C DTCG — figmascope precede la pubblicazione delle specifiche finali e non implementa tipi compositi come fontFamily — ma è abbastanza vicino da poter essere analizzato da strumenti consapevoli di DTCG con adattamenti minimi.
L'oggetto typography vuoto non è un bug. È spiegato di seguito.
Naming delle chiavi derivato dal valore
Quando un file Figma ha Variables, le chiavi dei token provengono dai nomi di Variable impostati dal designer. spacing.md, color.brand.primary, qualsiasi cosa usi il design system.
Quando un file Figma non ha Variables — il che vale per la maggior parte dei file Figma reali — figmascope torna al naming derivato dal valore. Un valore di spacing di 16 diventa spacing.16. Un colore #7f5cfe diventa color.7f5cfe. Un corner radius di 4 diventa radius.4.
Questo è un compromesso deliberato. I nomi derivati dal valore sono brutti ma stabili. Sono derivati dal valore effettivo, quindi due esecuzioni diverse dello stesso file Figma producono la stessa chiave. spacing.16 significa sempre 16dp. L'agente può farci affidamento.
L'alternativa sarebbe nomi posizionali come spacing.1, spacing.2 ecc. Quelli sono fragili — aggiungi un valore di spacing più piccolo e tutto si sposta. I nomi derivati dal valore non si spostano.
I nomi derivati dal valore sono un fallback per i file che dovrebbero avere Variables ma non ce le hanno. Se il tuo design system ha 40 valori di spacing che necessitano tutti di nomi semantici, spinge il designer a configurare le Variables. Il fallback dell'inferenza esiste per i file del mondo reale, non come sostituto di un vero sistema di token. Puoi eseguire figmascope sul tuo file per vedere quale percorso di sourcing viene utilizzato.
Il campo tokensSource e cosa significa
_meta.json include un campo tokensSource che ti dice come sono stati derivati i token:
| Valore | Significato |
|---|---|
"figma-variables" |
Il file Figma ha Variables e sono state usate direttamente. I nomi dei token sono assegnati dal designer. Copertura completa. |
"inferred-from-frequency" |
Nessuna Variable. figmascope ha scansionato tutti i nodi, trovato valori ricorrenti frequenti, promossi a token. La copertura dipende dalla coerenza del design. |
"none" |
Nessuna Variable e l'inferenza non ha prodotto nulla di utile. tokens.json avrà sezioni vuote o quasi vuote. |
L'avviso "tokens-inferred-from-frequency" in _meta.json rispecchia questo. Se lo vedi, la copertura dei token è best-effort.
Quando tokensSource è "inferred-from-frequency", l'algoritmo di inferenza è: trova tutti i valori di dimensione che appaiono nei campi padding, gap o cornerRadius di tre o più nodi. Promuovili rispettivamente a token di spacing o radius. Fai lo stesso per i colori di fill. I valori che appaiono solo una o due volte sono trattati come one-off, non promossi.
Funziona bene per design internamente coerenti. Funziona male per design esplorativi dove lo spacing varia liberamente. Gli avvisi di _meta.json esistono precisamente affinché l'agente sappia in quale situazione si trova.
Perché typography è spesso vuoto
I token di typography richiedono Figma Variables con tipo FLOAT o STRING per essere estratti in modo affidabile. Gli stili di testo esistono in Figma come stili condivisi, non Variables, e la superficie API per gli stili è diversa dall'API Variables.
figmascope v0.4 estrae la typography quando le Variables la coprono. Non tenta l'inferenza basata sulla frequenza per la typography perché i token di typography utili — famiglia di font, altezza della riga, spaziatura delle lettere, combinazioni di peso — non hanno nomi ovvi derivati dal valore come spacing.16. Una chiave fontSize.14 è molto meno utile di typography.body.small, e generare un nome sbagliato è peggio che non generarne nessuno.
Quindi il risultato è onesto: se il tuo file Figma ha Variables di typography, ottieni token di typography. In caso contrario, ottieni un oggetto vuoto e all'agente viene comunicato tramite CONTEXT.md che la copertura della typography potrebbe essere parziale.
// _meta.json
{
"tokensSource": "inferred-from-frequency",
"warnings": [
"tokens-inferred-from-frequency"
]
}
L'agente vede questo e sa di essere conservativo riguardo ai riferimenti ai token di typography. Genera codice fallback con valori espliciti e un commento TODO anziché inventare un nome di token.
Come l'agente usa tokens.json
Il vincolo CONTEXT.md è: "Non hardcodare mai valori dp se esiste un token entro ±2dp." La tolleranza ±2dp gestisce l'arrotondamento. Se un nodo ha paddingLeft: 15 e spacing.16 esiste, l'agente usa spacing.16. Se il token più vicino è spacing.24, nessuna corrispondenza — l'agente usa il valore letterale.
Per i colori, la corrispondenza è esatta sul valore hex dopo la normalizzazione a 6 cifre minuscole. #7F5CFE corrisponde a color.7f5cfe.
Per il corner radius, stessa regola ±2dp dello spacing.
L'output pratico per un target Jetpack Compose appare così:
// Con tokensSource figma-variables
Surface(
shape = RoundedCornerShape(Radius.radius8),
color = Color.Brand.Primary
) {
Column(
verticalArrangement = Arrangement.spacedBy(Spacing.spacing16),
modifier = Modifier.padding(horizontal = Spacing.spacing24)
) { ... }
}
// Con tokensSource inferred-from-frequency (stesso output visivo, stessi riferimenti token)
Surface(
shape = RoundedCornerShape(Radius.radius8),
color = Color.color7f5cfe
) { ... }
I nomi derivati dal valore sono meno leggibili. Sono comunque meglio dei valori hardcoded.
Confronto con altri approcci di estrazione token
Il pannello "Inspect" nativo di Figma mostra i valori per nodo. Non c'è un file token esportato. Dovresti crearne uno manualmente o usare un plugin come Tokens Studio. Entrambi richiedono sforzo da parte del designer e manutenzione continua.
figmascope estrae i token automaticamente ad ogni esportazione. Se il file cambia, riesporta e i token riflettono lo stato attuale. Il compromesso è che senza Variables i nomi sono derivati dal valore piuttosto che semantici — ma ottieni un file di token ogni volta, senza plugin o passaggi aggiuntivi nel flusso di lavoro.
Tokens Studio (ex integrazione Style Dictionary) richiede al designer di configurare il plugin, mantenere un file JSON nel file Figma e sincronizzarlo. Questa è la soluzione giusta per un design system maturo. L'approccio di figmascope è la soluzione giusta per i file che non ci sono ancora arrivati, che è la maggior parte dei file.
L'estrazione dei token è uno snapshot best-effort di ciò che esiste nel file. Non è un sostituto di un design system token-first. È lo strumento che usi mentre ci costruisci sopra.
Collegare tokens.json al tuo codebase
La struttura JSON è abbastanza piatta da rendere semplice la generazione di un oggetto Kotlin o di un modulo TypeScript. Un semplice script:
// tokens.json → oggetto Kotlin (semplificato)
const tokens = JSON.parse(fs.readFileSync('tokens.json', 'utf-8'));
let output = 'object Spacing {\n';
for (const [key, token] of Object.entries(tokens.spacing)) {
const name = key.replace('spacing.', 'spacing').replace('.', '_');
output += ` val ${name} = ${token.$value}.dp\n`;
}
output += '}';
// → val spacing16 = 16.dp
Se stai già usando una pipeline di design token, il formato W3C-ish è abbastanza vicino da poter essere inserito in Style Dictionary con un transformer personalizzato per le chiavi $value/$type.
Il resto di come i token interagiscono con l'IR è trattato in IR Per-Schermata. Per come i token interagiscono con il contesto agente più ampio, vedi Anatomia di CONTEXT.md. Per il flusso di lavoro di esportazione design token end to end, vedi Esportazione Design Token. Per esportare i token dal tuo file Figma, vai su figmascope.dev.