Analyse indépendante de la documentation publique pour développeurs de Stripe, écrite pour les personnes concevant leurs propres systèmes. Identity Forge n'est pas affilié à Stripe et n'est pas approuvé par Stripe. Stripe et son logo sont des marques déposées de leur propriétaire. Les détails présentés ici reflètent la documentation au moment de la rédaction ; veuillez vérifier sur docs.stripe.com avant de vous baser sur une valeur spécifique.
Ce que les gens recherchent n'existe pas publiquement
Les surfaces produits de Stripe (le Dashboard, le site marketing, la doc) reposent sur un système interne qui a porté divers noms au fil des ans et n'a jamais été publié sous forme de package public. Il n'y a pas de npm install, pas de Storybook, pas d'export de tokens. Si c'est ce que vous cherchiez, ce n'est pas disponible, et les reconstructions tierces ne sont que des déductions basées sur des captures d'écran.
Ce que Stripe publie, et documente minutieusement, ce sont deux systèmes destinés aux développeurs qui s'intègrent à Stripe. Ils sont généralement abordés séparément car ils se trouvent dans des sections différentes de la documentation. Lus ensemble, ils constituent une véritable masterclass sur les limites d'un design system.
| Stripe Apps UI toolkit | Elements Appearance API | |
|---|---|---|
| Lieu de rendu de l'UI | Dans le Dashboard Stripe | Dans votre produit |
| Marque dominante | Celle de Stripe | La vôtre |
| CSS arbitraire | Impossible. La prop css n'accepte que des tokens | Supporté, via la map rules |
| Espacement | Sept paliers nommés et fixes | Un spacingUnit que vous définissez ; tout en dérive |
| Stylisation des composants | Prédéfinie ; certains composants refusent toute surcharge | Personnalisable jusqu'aux sélecteurs et états individuels |
| Ce qu'il optimise | La cohérence à travers des milliers d'applications tierces | S'intégrer dans un checkout que vous n'avez pas conçu |
La distinction entre les deux n'est pas technique. C'est une limite de confiance. Lorsque votre UI repose sur la surface de Stripe, Stripe ne peut pas permettre qu'une application tierce mal stylisée donne au Dashboard un aspect défectueux ; il supprime donc la possibilité de le faire. Lorsque l'UI de Stripe repose sur votre surface, un formulaire de paiement qui ignorerait votre design semblerait poser un problème de sécurité ; Stripe confie alors les commandes. Même entreprise, mêmes valeurs de design, mais des approches opposées, car la question n'est pas de savoir « à quoi cela devrait ressembler », mais « qui est responsable de son apparence ».
Stripe Apps : un design system imposé par la signature de type
Le toolkit UI de Stripe Apps vous fournit un ensemble de composants (vues, layout, navigation, contenu, formulaires, graphiques) ainsi qu'une primitive Box dotée d'une prop css. La prop css ressemble à une échappatoire de stylisation, mais elle ne l'est pas. Elle n'accepte que des tokens nommés, rien d'autre.
<Box css={{
stack: 'y',
gap: 'medium',
padding: 'large',
backgroundColor: 'surface',
borderRadius: 'medium',
}} />
// gap: 'medium' ✅ a token
// gap: '17px' ❌ not in the vocabularyLe vocabulaire d'espacement se compose de sept étapes et d'un zéro, documentés avec des valeurs de pixels fixes : xxsmall 2px, xsmall 4px, small 8px, medium 16px, large 24px, xlarge 32px, xxlarge 48px. Le dimensionnement est fractionnaire (demis, tiers, quarts, cinquièmes, sixièmes, douzièmes, plus fill) avec des options min, max et fit basées sur le contenu.
Notez les ratios de cette échelle d'espacement. Elle n'est pas linéaire (2, 4, 8, 16, 24, 32, 48) : elle double sur la partie basse où les différences de 2px sont visibles, puis progresse par pas de 8 sur la partie haute où elles ne le sont plus. Une échelle qui doublerait jusqu'à 128 gaspillerait des étapes inutiles ; une échelle qui progresserait par pas de 4 sur toute la longueur vous donnerait treize valeurs qui se ressemblent toutes.
Le point intéressant réside dans ce qui se passe au-dessus de Box. Les composants autres que Box et Inline possèdent des styles prédéfinis, et la documentation précise explicitement que certains d'entre eux ne peuvent pas être modifiés : un composant dont l'apparence change selon les callbacks implémentés ne permettra pas de contredire ce comportement, car l'apparence véhicule ici une signification. D'autres exposent une petite énumération : Button propose primary, le style par défaut et destructive, et la liste s'arrête là. Quelques-uns exposent une seule propriété, comme Icon qui accepte fill.
Il existe également un ensemble documenté de contraintes de hiérarchie des composants : des règles sur quels composants peuvent en contenir d'autres. C'est l'équivalent du layout pour cette même idée : il ne s'agit pas de conseils sur une bonne structure, mais d'une restriction qui fait échouer une mauvaise structure plutôt que de la livrer.
La leçon : l'imposition l'emporte sur la documentation
Presque chaque design system est un projet de documentation. Il préconise d'utiliser les tokens, puis livre une prop className qui accepte n'importe quoi, et six mois plus tard, la moitié de la base de code contient des valeurs hexadécimales arbitraires parce que quelqu'un était pressé un vendredi.
Stripe Apps supprime cette option. Il n'y a aucun chemin allant de « être pressé » à #3c82f6, car la prop ne l'acceptera pas. C'est une garantie bien plus forte qu'une règle de linting et infiniment plus forte qu'un paragraphe dans un wiki. Si vous maintenez un système qui doit survivre à des contributeurs qui n'ont pas lu la doc, ce qui est le cas de tous, c'est la solution à adopter.
C'est aussi la solution qui a le coût le plus élevé, et il faut être honnête à ce sujet. Un vocabulaire fermé signifie que chaque nouvelle exigence réelle devient une demande adressée aux propriétaires du système. C'est tolérable lorsque les propriétaires sont une équipe plateforme financée au service d'une place de marché d'applications. C'est insupportable lorsqu'il s'agit d'une seule personne maintenant un système pour quatre squads produit qui ont toutes des échéances.
Éléments : l'échelle à trois niveaux
L'API Appearance résout le problème inverse. Un formulaire de paiement doit sembler natif sur un site que personne chez Stripe n'a vu, tout en conservant un layout que Stripe contrôle pour des raisons de conversion et de conformité. La réponse de Stripe est une échelle à trois échelons, et la documentation vous dit de la gravir dans l'ordre.
- 1
Choisissez un thème
Trois points de départ préconstruits :
stripe,night,flat. Une ligne, et la plupart des intégrations qui nécessitent simplement de ne pas entrer en conflit sont terminées.const appearance = { theme: 'night' } - 2
Définissez les variables
Un petit ensemble de valeurs qui se propagent partout. C'est la couche des tokens, et c'est là que se produit la majorité de la personnalisation réelle.
const appearance = { theme: 'stripe', variables: { colorPrimary: '#0570de', colorBackground: '#ffffff', colorText: '#30313d', colorDanger: '#df1b41', fontFamily: 'Ideal Sans, system-ui, sans-serif', spacingUnit: '2px', borderRadius: '4px', }, } - 3
Ajoutez des règles, seulement si vous en avez encore besoin
Une map de sélecteurs de type CSS vers des propriétés CSS, atteignant les composants et les états individuels. C'est l'échappatoire, et elle est délibérément placée en dernier.
const appearance = { rules: { '.Tab': { border: '1px solid #E0E6EB' }, '.Tab:hover': { color: 'var(--colorText)' }, '.Tab--selected': { borderColor: '#E0E6EB' }, }, }
L'ordre est le design. Chaque échelon est plus puissant et plus coûteux à maintenir que celui du dessous, et la documentation vous pousse vers le bas de l'échelle plutôt que vers le haut. Une équipe qui commence par rules écrit quarante sélecteurs et en est responsable pour toujours ; une équipe qui commence par theme écrit une ligne et ne descend que lorsqu'elle y est réellement contrainte.
spacingUnit est l'idée de design de token qu'il faut voler
Parmi les variables, deux méritent attention car elles sont des bases dérivées plutôt que des valeurs. spacingUnit est décrite comme l'unité de base dont découlent tous les autres espacements : augmentez-la et tout le composant devient plus spacieux. fontSizeBase définit la taille racine, et les autres variables de taille de police s'adaptent à partir d'elle en rem.
Comparez cela avec l'approche habituelle, où un design system publie --space-1 à --space-12 comme douze valeurs indépendantes codées en dur. Les deux vous donnent une échelle. Une seule vous donne un curseur. Si un client a besoin d'un formulaire plus dense, la version dérivée ne nécessite qu'un seul nombre ; la version énumérée nécessite douze modifications et un arbitrage pour chacune.
/* Enumerated: twelve values, twelve things to change */
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
/* ... */
/* Derived: one dial */
--space-unit: 4px;
--space-1: calc(var(--space-unit) * 1);
--space-2: calc(var(--space-unit) * 2);
--space-3: calc(var(--space-unit) * 3);Cela vaut la peine d'être appliqué au-delà de l'espacement. Toute échelle où les étapes sont véritablement proportionnelles (espacement, typographie, rayon) est mieux exprimée par une base plus un ratio que par une liste. Les échelles où les étapes ne sont pas proportionnelles, comme une rampe de couleurs neutres, ne le sont pas : celles-ci nécessitent que chaque étape soit choisie à l'œil.
Les exceptions documentées sont la partie honnête
La documentation de l'API Appearance stipule que colorPrimary, colorBackground, colorText, colorSuccess, colorDanger et colorWarning ne supportent pas la syntaxe rgba() ou var(--myVariable), alors que d'autres variables le font. Elle note également que l'API ne s'applique pas aux Elements de méthodes de paiement individuels comme CardElement, qui utilisent un objet Style distinct.
Ce sont des incohérences peu glamour, et les publier est la bonne décision. Une API de personnalisation qui échoue silencieusement sur un sous-ensemble d'entrées coûte une après-midi de débogage confus à un intégrateur ; une API qui l'indique dans le tableau ne lui coûte que trente secondes. Si votre propre système possède une règle qui ne fonctionne que dans certains cas, la documentation est l'endroit où elle doit figurer, pas le journal des modifications.
Appliquer les deux modèles à un système orienté agent
Ces deux systèmes ont été conçus pour des développeurs humains lisant de la documentation. La question intéressante en 2026 est ce qui change lorsque le développeur est un agent de code, et la réponse est que la posture de Stripe Apps se renforce tandis que celle d'Elements s'affaiblit.
Un agent n'a aucune incitation à bâcler le travail un vendredi, mais il n'a pas non plus de mémoire de vos conventions entre deux sessions. Donnez-lui un vocabulaire fermé et il utilisera ce vocabulaire, de manière fiable, pour toujours. Donnez-lui une prop className et un paragraphe disant « préférez les tokens » et il utilisera les tokens à peu près aussi souvent que les données d'entraînement, c'est-à-dire, parfois.
Nous avons échantillonné 299 fichiers DESIGN.md publiés pour être lus par des agents IA. 86 % spécifiaient les couleurs sous forme de valeurs hexadécimales brutes sans rôle sémantique attaché, et 76 % ne contenaient aucune interdiction du tout. Ces deux chiffres décrivent un fichier qui indique à un modèle quelles couleurs existent et rien sur ce qu'elles signifient ou ce qui est interdit : l'exact opposé des deux systèmes de Stripe, qui portent presque entièrement sur la signification et la contrainte.
| Ce que le modèle en fait | |
|---|---|
Primary: #0570de | L'utilise partout où le bleu semble raisonnable : titres, liens, bordures, un dégradé |
--color-primary: #0570de: uniquement pour les actions primaires et l'état actif. Jamais pour le texte, les bordures ou les fonds. | L'utilise sur les actions primaires et l'état actif. C'est l'interdiction qui fait la différence |
Spacing: 4, 8, 12, 16, 24, 32 | Utilise principalement ces valeurs, produit occasionnellement du 14px ou 20px lorsque la mise en page est serrée |
Spacing scale is xs/sm/md/lg/xl only. Any other value is a bug. | Reste dans l'échelle, car le fichier a défini ce qui est considéré comme incorrect |
C'est l'idée de Stripe Apps transposée en prose : on ne peut pas donner d'erreur de type à un agent, mais on peut lui indiquer ce qui en constituerait une. L'idée d'Elements s'applique également sous forme d'ordonnancement : énoncer d'abord les valeurs par défaut au niveau du thème, puis les tokens, puis les exceptions spécifiques, afin qu'un modèle lisant de haut en bas rencontre la règle générale avant le cas particulier.
Les kits de design d'Identity Forge sont bâtis exactement sur ce modèle : des rôles sémantiques plutôt que du hex brut, une liste explicite de ce qu'il faut faire et ne pas faire, et des motifs qui décrivent l'intention du design plutôt que les valeurs qu'il contient. Parcourez les kits ou commencez par ce qu'est un fichier DESIGN.md.
Ce qu'il faut en retenir
La plupart des équipes qui créent un design system choisissent une posture unique et l'appliquent partout. La documentation de Stripe démontre que la posture doit suivre la limite de responsabilité. Sur les surfaces dont vous êtes responsable, fermez le vocabulaire et rendez les violations impossibles. Sur les surfaces dont quelqu'un d'autre est responsable, publiez une échelle et laissez-les monter seulement aussi haut que nécessaire.
La plupart des produits possèdent ces deux types de surfaces. L'outil d'administration interne et le widget intégrable ne représentent pas le même problème de design, et un système unique avec une seule stratégie de personnalisation servira mal l'un des deux.
Puis-je télécharger le design system de Stripe ?
Pas celui utilisé en interne pour le Dashboard et le site marketing. Il n'a jamais été publié sous forme de package ou de site de documentation. Le kit UI de Stripe Apps et l'API Appearance d'Elements sont tous deux publics et documentés, mais ce sont des systèmes pour s'intégrer à Stripe, pas pour construire votre propre produit.
Quelle est la différence entre Stripe Elements et le kit UI de Stripe Apps ?
Elements est l'interface de paiement de Stripe que vous intégrez à votre site, stylisée pour correspondre à votre marque via l'API Appearance. Le kit UI de Stripe Apps est une bibliothèque de composants pour créer des applications qui s'exécutent à l'intérieur du Dashboard Stripe, stylisée pour correspondre à la marque de Stripe sans possibilité d'override. Surfaces différentes, propriétaires du visuel différents.
Puis-je utiliser du CSS arbitraire dans une application Stripe App ?
Non. La prop css sur Box accepte des tokens nommés plutôt que des valeurs libres, plusieurs composants possèdent des presets qui ne peuvent être modifiés, et des contraintes de hiérarchie de composants restreignent ce qui peut en contenir un autre. C'est délibéré. Cela empêche des milliers d'applications tierces de rendre le Dashboard incohérent.
Dois-je personnaliser Stripe Elements avec des variables ou des règles ?
Les variables d'abord, toujours. Elles se propagent sur l'ensemble de l'Element et restent correctes lorsque Stripe met à jour l'interne. Ne passez aux rules que pour ce que les variables ne peuvent réellement pas exprimer, car chaque règle que vous écrivez est un sélecteur dont vous devenez responsable face aux futures modifications du balisage.
Qu'est-ce que spacingUnit modifie concrètement dans Stripe Elements ?
C'est la valeur de base dont dérive tout l'espacement de l'Element ; l'augmenter ou la diminuer rend donc l'ensemble du composant uniformément plus ou moins aéré sans rien toucher d'autre. C'est un curseur unique plutôt qu'une liste d'écarts codés en dur, un modèle qui mérite d'être copié dans votre propre couche de tokens.