Design & UX

Extraire les design tokens depuis Figma avec l’API Variables

13 min de lecture

Vos maquettes Figma contiennent déjà votre charte : couleurs, espacements, rayons, typographies. Le problème, c’est que ces valeurs vivent dans un fichier de design et que vos développeurs les recopient à la main dans le CSS — au pixel près, en espérant ne pas se tromper. À la moindre évolution de la charte, tout est à refaire. Ce tutoriel vous apprend à extraire ces valeurs par programme depuis Figma, sous forme de design tokens exploitables par n’importe quelle base de code.

📍 Guide principal de la série : Du design au code : Figma, tokens et WCAG 2.2 côté développeur. Lisez-le d’abord pour la vue d’ensemble ; ce tutoriel approfondit la première brique : l’extraction des tokens.

🎯 Ce que vous allez apprendre

  • Distinguer une Variable Figma d’un Style, et comprendre pourquoi seules les Variables servent de source de tokens.
  • Générer un jeton d’accès Figma avec les bons scopes et appeler l’API REST Variables en toute sécurité.
  • Lire la réponse de l’endpoint variables/local : collections, modes, valeurs par mode.
  • Résoudre les alias (une variable qui pointe vers une autre) pour obtenir des valeurs finales.
  • Produire un fichier .tokens.json conforme au format standard du W3C, prêt à être consommé par un outil de build.

🛠️ Ce que vous allez construire

Un petit script Node.js, fetch-tokens.mjs, qui interroge un fichier Figma et écrit un fichier tokens/figma.tokens.json. Ce fichier deviendra l’entrée du pipeline de génération multiplateforme que construit le tutoriel suivant. À la fin, une commande unique régénérera vos tokens à partir de la dernière version de la maquette — fini la recopie manuelle.

Prérequis

  • Node.js 20 ou plus récent (l’API fetch est native, aucun paquet HTTP à installer).
  • Un compte Figma avec accès à un fichier contenant des Variables. Point important : l’API REST Variables n’est ouverte qu’aux membres d’une organisation Enterprise. Si vous n’avez pas ce plan, l’étape 7 décrit l’alternative gratuite via le plugin Tokens Studio.
  • Savoir lire du JSON et lancer une commande dans un terminal. Si node --version répond un numéro, vous êtes prêt.
  • ⏱️ Temps estimé : ~40 minutes.

Étape 1 — Comprendre Variables et Styles : pourquoi la distinction compte

Avant d’écrire une ligne de code, il faut comprendre ce qu’on extrait. Figma propose deux mécanismes pour stocker des valeurs réutilisables, et ils ne se valent pas pour notre objectif.

Les Styles (Color styles, Text styles, Effect styles) sont l’ancien système : ils regroupent des propriétés sous un nom, mais une couleur de style est figée — elle ne change pas selon un thème clair ou sombre. Les Variables, introduites plus tard, sont le système moderne : chaque variable a un type (couleur, nombre, chaîne, booléen) et peut prendre une valeur différente selon le mode actif (par exemple « clair » et « sombre »). C’est exactement la définition d’un design token : une valeur nommée, typée, et déclinable par contexte.

Conséquence pratique : on extrait les Variables, pas les Styles. Dans Figma, ouvrez le panneau de droite, onglet Local variables : vous y verrez vos collections (souvent « Primitives », « Sémantique », « Composants ») et, pour chacune, les modes définis. Retenez ce vocabulaire — collection, mode, variable — car la réponse de l’API reprend exactement cette structure.

Étape 2 — Générer un jeton d’accès avec les bons scopes

L’API REST de Figma s’authentifie avec un jeton personnel. Un jeton trop permissif est un risque de sécurité ; on lui donne donc uniquement la portée nécessaire. Pour lire des variables, le scope requis est file_variables:read.

Dans Figma : cliquez sur votre avatar, puis Settings → Security → Personal access tokens → Generate new token. Donnez-lui un nom explicite (par exemple « extraction-tokens-ci »), cochez le scope File variables : Read only, puis copiez la valeur affichée. Elle ne sera plus jamais affichée : stockez-la immédiatement.

On ne met jamais un jeton en clair dans le code. On l’expose en variable d’environnement :

# macOS / Linux
export FIGMA_TOKEN="figd_votre_jeton_ici"
export FIGMA_FILE_KEY="abc123DEF456"

# Windows PowerShell
$env:FIGMA_TOKEN = "figd_votre_jeton_ici"
$env:FIGMA_FILE_KEY = "abc123DEF456"

La clé du fichier (FILE_KEY) se lit dans l’URL Figma : figma.com/design/abc123DEF456/Nom-du-fichier. C’est le segment juste après /design/. Une fois ces deux variables exportées, vérifiez avec echo $FIGMA_FILE_KEY (ou echo $env:FIGMA_FILE_KEY sous PowerShell) que la valeur est bien là avant de continuer.

Point d’étape — Vous avez un jeton au scope file_variables:read et la clé du fichier, tous deux en variables d’environnement. Si echo renvoie une chaîne vide, l’export n’a pas pris : relancez-le dans le même terminal que celui où vous exécuterez le script.

Étape 3 — Appeler l’endpoint variables/local

L’endpoint qui nous intéresse est GET /v1/files/:file_key/variables/local. Il renvoie toutes les variables locales du fichier (celles définies dedans, pas celles importées d’une bibliothèque). L’authentification passe par l’en-tête X-Figma-Token. Testons d’abord avec curl pour valider l’accès avant d’écrire le script :

curl -s -H "X-Figma-Token: $FIGMA_TOKEN" \
  "https://api.figma.com/v1/files/$FIGMA_FILE_KEY/variables/local" | head -c 400

Si tout va bien, vous voyez du JSON commençant par {"status":200,"error":false,"meta":{.... Une réponse 403 signifie le plus souvent que votre compte n’est pas sur un plan Enterprise, ou que le scope du jeton est insuffisant : revenez à l’étape 2. Le drapeau -s rend curl silencieux et head -c 400 tronque l’affichage pour ne pas noyer le terminal.

Étape 4 — Lire la structure de la réponse

Tout ce qui nous intéresse est dans l’objet meta, qui contient deux dictionnaires : variableCollections et variables, indexés par identifiant. Voici une réponse réduite à l’essentiel :

{
  "meta": {
    "variableCollections": {
      "VariableCollectionId:1:2": {
        "id": "VariableCollectionId:1:2",
        "name": "Sémantique",
        "modes": [
          { "modeId": "1:0", "name": "Clair" },
          { "modeId": "1:1", "name": "Sombre" }
        ],
        "defaultModeId": "1:0",
        "variableIds": ["VariableID:3:10", "VariableID:3:11"]
      }
    },
    "variables": {
      "VariableID:3:10": {
        "id": "VariableID:3:10",
        "name": "color/surface",
        "resolvedType": "COLOR",
        "valuesByMode": {
          "1:0": { "r": 1, "g": 1, "b": 1, "a": 1 },
          "1:1": { "r": 0.07, "g": 0.07, "b": 0.09, "a": 1 }
        }
      }
    }
  }
}

Trois choses à retenir. D’abord, resolvedType vaut COLOR, FLOAT, STRING ou BOOLEAN — c’est le type final de la variable. Ensuite, valuesByMode associe chaque modeId à une valeur : ici, color/surface est blanc en mode Clair et presque noir en mode Sombre. Enfin, les couleurs sont des objets {r,g,b,a} avec des composantes flottantes entre 0 et 1, et non des codes hexadécimaux : il faudra les convertir.

Étape 5 — Résoudre les alias

Un bon système de tokens n’écrit pas deux fois la même couleur. On définit des primitives (par exemple blue/600 = un bleu précis) puis des tokens sémantiques qui y font référence (color/action = blue/600). Dans l’API, cette référence apparaît dans valuesByMode sous une forme particulière :

"valuesByMode": {
  "1:0": { "type": "VARIABLE_ALIAS", "id": "VariableID:3:99" }
}

Au lieu d’une couleur, on a un objet VARIABLE_ALIAS qui pointe vers une autre variable par son id. Pour obtenir la valeur réelle, il faut suivre ce pointeur jusqu’à tomber sur une valeur concrète. Deux stratégies existent : aplatir (remplacer l’alias par la valeur finale) ou conserver la référence (la traduire en référence de token, par exemple {color.blue.600}). La seconde préserve la sémantique et c’est celle que privilégie le format standard ; nous l’adopterons. Concrètement, on traduit chaque alias en chemin de token entre accolades.

Point d’étape — Vous savez maintenant lire une variable simple et reconnaître un alias. Vérifiez sur votre propre réponse : repérez au moins une variable dont une valeur de mode est un objet VARIABLE_ALIAS. Si vous n’en avez aucune, c’est que votre fichier n’utilise pas encore de tokens sémantiques — ce n’est pas bloquant pour la suite.

Étape 6 — Convertir vers le format de tokens du W3C

Pour que nos tokens soient consommables par d’autres outils sans dépendre de Figma, on les écrit dans le format standardisé par le Design Tokens Community Group du W3C, dont la première version stable est parue fin octobre 2025. Ce format est simple : chaque token est un objet avec une propriété $value et une propriété $type. Les groupes sont des objets imbriqués. Exemple cible :

{
  "color": {
    "surface": { "$type": "color", "$value": "#ffffff" },
    "action":  { "$type": "color", "$value": "{color.blue.600}" }
  },
  "space": {
    "md": { "$type": "dimension", "$value": "16px" }
  }
}

La référence {color.blue.600} est la traduction de l’alias vu à l’étape 5 : on remplace les barres obliques du nom Figma (color/blue/600) par des points et on entoure d’accolades. Pour les couleurs, on convertit l’objet {r,g,b,a} en hexadécimal ; pour les nombres de type espacement ou rayon, on ajoute l’unité px.

Étape 7 — Le script complet et sa vérification

Voici fetch-tokens.mjs. Il télécharge les variables, parcourt les collections et leurs modes, convertit chaque valeur, et écrit le fichier. Lisez les commentaires : chaque bloc correspond à une étape déjà expliquée.

import { writeFile, mkdir } from 'node:fs/promises';

const TOKEN = process.env.FIGMA_TOKEN;
const FILE  = process.env.FIGMA_FILE_KEY;
const API   = 'https://api.figma.com/v1/files/' + FILE + '/variables/local';

// 1. Récupération
const res = await fetch(API, { headers: { 'X-Figma-Token': TOKEN } });
if (!res.ok) throw new Error('Figma a répondu ' + res.status);
const { meta } = await res.json();

// 2. Index id -> nom de token (color/blue/600 -> color.blue.600)
const nameOf = (id) => meta.variables[id].name.split('/').join('.');

// 3. Conversion d'une couleur {r,g,b,a} -> #rrggbb
function toHex(c) {
  const h = (n) => Math.round(n * 255).toString(16).padStart(2, '0');
  return '#' + h(c.r) + h(c.g) + h(c.b);
}

// 4. Conversion d'une valeur de mode
function convert(value, type) {
  if (value && value.type === 'VARIABLE_ALIAS') {
    return '{' + nameOf(value.id) + '}';          // alias -> référence
  }
  if (type === 'COLOR')  return toHex(value);
  if (type === 'FLOAT')  return value + 'px';
  return String(value);
}

// 5. Construction de l'arbre de tokens (mode par défaut de chaque collection)
const tokens = {};
for (const col of Object.values(meta.variableCollections)) {
  const mode = col.defaultModeId;
  for (const id of col.variableIds) {
    const v = meta.variables[id];
    const path = v.name.split('/');
    let node = tokens;
    path.forEach((seg, i) => {
      if (i === path.length - 1) {
        node[seg] = {
          '$type': v.resolvedType === 'COLOR' ? 'color' : 'dimension',
          '$value': convert(v.valuesByMode[mode], v.resolvedType)
        };
      } else {
        node[seg] = node[seg] || {};
        node = node[seg];
      }
    });
  }
}

// 6. Écriture
await mkdir('tokens', { recursive: true });
await writeFile('tokens/figma.tokens.json', JSON.stringify(tokens, null, 2));
console.log('OK — ' + Object.keys(meta.variables).length + ' variables exportées');

Lancez-le : node fetch-tokens.mjs. Vous devez voir OK — N variables exportées et trouver le fichier tokens/figma.tokens.json sur le disque. Ouvrez-le : la hiérarchie doit refléter vos noms Figma, les couleurs être en hexadécimal et les alias apparaître entre accolades. Si le script s’arrête sur Figma a répondu 403, le problème est l’accès (plan ou scope), pas le code. S’il écrit un fichier vide, c’est que le fichier Figma ne contient aucune variable locale.

Notez que ce script n’exporte que le mode par défaut de chaque collection. Gérer plusieurs thèmes (clair/sombre) consiste à boucler sur col.modes et à produire un fichier par mode — c’est l’exercice proposé plus bas.

L’alternative gratuite : le plugin Tokens Studio

Si vous n’êtes pas sur un plan Enterprise, l’API REST Variables vous est fermée. La voie gratuite passe par le plugin Tokens Studio for Figma, qui stocke vos tokens directement au format W3C et peut les exporter en JSON ou les synchroniser avec un dépôt Git. Vous obtenez alors le même tokens.json, mais géré dans le plugin plutôt que dans les Variables natives. Le reste de la série (build multiplateforme, intégration) fonctionne à l’identique, puisque le format de sortie est le même standard.

🐞 Pièges fréquents

Symptôme Cause probable Correctif
403 Forbidden Compte hors plan Enterprise ou scope manquant Vérifier le scope file_variables:read ; sinon utiliser Tokens Studio
Réponse vide (variables: {}) Le fichier utilise des Styles, pas des Variables Migrer les Styles vers des Variables dans Figma
Couleurs « fausses » Oubli de la conversion 0–1 vers 0–255 Multiplier chaque composante par 255 avant l’hexa
Alias non résolus dans le rendu final Le consommateur ne sait pas suivre {...} Confier la résolution à l’outil de build (tutoriel suivant)
Jeton invalide en CI Variable d’environnement non transmise au job Déclarer le secret dans les réglages du pipeline

✅ Récapitulatif

Vous êtes parti d’un fichier Figma et vous en avez extrait, par programme, un fichier de design tokens au format standard du W3C. Vous savez distinguer Variables et Styles, authentifier un appel API avec le scope minimal, lire la structure collections / modes / valuesByMode, reconnaître et traduire les alias, et convertir les valeurs brutes en valeurs exploitables. Surtout, cette extraction est répétable : une commande suffit pour resynchroniser après chaque évolution de la maquette.

🧾 Aide-mémoire

Élément Rôle
GET /v1/files/:key/variables/local Liste les variables locales du fichier
En-tête X-Figma-Token Authentification par jeton personnel
Scope file_variables:read Permission minimale de lecture
meta.variableCollections Collections + modes + liste des variables
valuesByMode[modeId] Valeur d’une variable pour un mode donné
{ type: "VARIABLE_ALIAS", id } Référence vers une autre variable
$type / $value Propriétés d’un token au format W3C

💪 À vous de jouer

Le script n’exporte que le mode par défaut. Modifiez-le pour générer un fichier par mode : tokens/figma.clair.tokens.json et tokens/figma.sombre.tokens.json, en bouclant sur col.modes et en lisant valuesByMode[mode.modeId].

Voir une piste de solution

Englobez la construction de l’arbre dans une boucle for (const mode of col.modes), écrivez dans un dictionnaire byMode[mode.name], puis faites un writeFile par entrée. Le nom de fichier se déduit de mode.name passé en minuscules. Attention : la résolution d’alias doit utiliser le même mode, sinon un token sombre pourrait pointer vers une primitive claire.

Tutoriels de la série

Pour aller plus loin

FAQ

L’API Variables est-elle vraiment réservée à Enterprise ?
Oui, la lecture des variables par l’API REST est restreinte aux membres d’une organisation Enterprise. Les autres plans passent par le plugin Tokens Studio, qui produit le même format de sortie.

Pourquoi ne pas exporter directement en CSS depuis ce script ?
On sépare volontairement l’extraction (dépendante de Figma) de la génération (indépendante). Un fichier de tokens neutre peut alimenter le CSS, mais aussi le JavaScript, iOS ou Android — c’est tout l’intérêt du format standard.

Que se passe-t-il si je renomme une variable dans Figma ?
Le name change donc le chemin du token change aussi. Pour des références stables côté code, certaines équipes s’appuient sur le champ codeSyntax de la variable, qui permet de fixer un nom destiné au code indépendamment du nom d’affichage.

Combien d’appels API puis-je faire ?
Figma applique des limites de débit. Pour un usage en intégration continue, un appel par build suffit largement ; inutile de poller en continu.

Service ITSkillsCenter

Application mobile Android et iOS

Création d'application mobile Android et iOS. À partir de 350 000 FCFA.

Démarrer mon projet
Publicité