<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ibrahima D.</title>
    <description>The latest articles on DEV Community by Ibrahima D. (@ibrahimdans).</description>
    <link>https://dev.to/ibrahimdans</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1002326%2F52fc8ac0-d5ec-492f-ab46-1fd9c95b716c.jpeg</url>
      <title>DEV Community: Ibrahima D.</title>
      <link>https://dev.to/ibrahimdans</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ibrahimdans"/>
    <language>en</language>
    <item>
      <title>Build a multi-platform Design System, step by step</title>
      <dc:creator>Ibrahima D.</dc:creator>
      <pubDate>Mon, 08 Jun 2026 09:11:30 +0000</pubDate>
      <link>https://dev.to/ibrahimdans/ets-build-a-multi-platform-design-system-step-by-step-poc-4a7d</link>
      <guid>https://dev.to/ibrahimdans/ets-build-a-multi-platform-design-system-step-by-step-poc-4a7d</guid>
      <description>&lt;h2&gt;
  
  
  Let's build a multi-platform Design System, step by step
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Web, iOS, Android. One color definition. Changed once, propagated everywhere.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of a theory article, we're going to &lt;strong&gt;build a working POC&lt;/strong&gt;, step by step. By the end, you'll have a mini design system that generates CSS, Swift, and Kotlin from a single source, with two brands, light/dark themes, a demo, and regression tests. All the code is on &lt;a href="https://github.com/ibrahimdans/design-system-poc" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; — clone it and follow along.&lt;/p&gt;

&lt;p&gt;The guiding thread: &lt;strong&gt;a design decision should exist in only one place, in a neutral form; everything else is derived from it automatically.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem we're solving
&lt;/h2&gt;

&lt;p&gt;Your brand's primary color — a blue — lives in parallel in CSS variables (web), Swift (iOS), Kotlin (Android)… The problem isn't &lt;em&gt;creating&lt;/em&gt; those values, it's &lt;strong&gt;keeping them in sync over time&lt;/strong&gt;. One day someone changes the blue on web but not on Android, and the product becomes inconsistent. Multiply by 2 brands and 2 themes: the inconsistency becomes structural.&lt;/p&gt;

&lt;p&gt;The root cause: &lt;strong&gt;the same decision is copied by hand into different formats.&lt;/strong&gt; We're going to kill the copy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 0 — The project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;design-system-poc &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;design-system-poc
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; style-dictionary typescript @types/node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://styledictionary.com/" rel="noopener noreferrer"&gt;Style Dictionary&lt;/a&gt; is the reference tool for turning "tokens → multiple targets". Add &lt;code&gt;"type": "module"&lt;/code&gt; to your &lt;code&gt;package.json&lt;/code&gt; (we write ESM) and a &lt;code&gt;tsconfig.json&lt;/code&gt; in &lt;code&gt;strict&lt;/code&gt; mode. We code in &lt;strong&gt;TypeScript&lt;/strong&gt;: Node 24 runs it natively (type stripping), so &lt;code&gt;node build.ts&lt;/code&gt; works with no compile step — &lt;code&gt;tsc --noEmit&lt;/code&gt; is only there for type-checking.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1 — Primitives (the &lt;em&gt;ingredients&lt;/em&gt;)
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;design token&lt;/strong&gt; is a &lt;code&gt;name → value&lt;/code&gt; pair describing a design intent, independent of any language. We start with the raw palette, with no business meaning.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tokens/primitives.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"blue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"300"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#60A5FA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
               &lt;/span&gt;&lt;span class="nl"&gt;"500"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#2563EB"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
               &lt;/span&gt;&lt;span class="nl"&gt;"700"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#1D4ED8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"green"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"500"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#059669"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
               &lt;/span&gt;&lt;span class="nl"&gt;"700"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#047857"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"grey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#FFFFFF"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
               &lt;/span&gt;&lt;span class="nl"&gt;"100"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#F3F4F6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
               &lt;/span&gt;&lt;span class="nl"&gt;"900"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#111827"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"space"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8px"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"spacing"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16px"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"spacing"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"radius"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4px"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"borderRadius"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"md"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8px"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"borderRadius"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These values "know" nothing about web or mobile. They're the &lt;strong&gt;neutral form&lt;/strong&gt; everything else will derive from.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2 — Semantic tokens (the secret to multi-brand)
&lt;/h2&gt;

&lt;p&gt;The beginner trap: putting &lt;code&gt;#2563EB&lt;/code&gt; directly in components. Instead, we create a &lt;strong&gt;semantic level&lt;/strong&gt; that describes &lt;em&gt;usage&lt;/em&gt; and &lt;strong&gt;points to a primitive&lt;/strong&gt; (the &lt;code&gt;{color.blue.500}&lt;/code&gt; syntax is a Style Dictionary reference).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tokens/semantic.brandA.light.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.blue.500}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"primary-hover"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.blue.700}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"on-primary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.grey.0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"surface"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.grey.0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"on-surface"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.grey.900}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;dark&lt;/strong&gt; theme keeps the &lt;em&gt;same semantic names&lt;/em&gt;, but rewires to different primitives — &lt;code&gt;tokens/semantic.brandA.dark.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.blue.300}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"surface"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.grey.900}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"on-surface"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.grey.100}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a &lt;strong&gt;2nd brand&lt;/strong&gt; = just different wiring — &lt;code&gt;tokens/semantic.brandB.light.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"primary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.green.500}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"primary-hover"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.green.700}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"surface"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{color.grey.0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"color"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; your components reference &lt;strong&gt;only&lt;/strong&gt; &lt;code&gt;color-primary&lt;/code&gt;, never &lt;code&gt;blue-500&lt;/code&gt;. Switching brand or theme = rewiring the semantic links, &lt;strong&gt;without touching a single line of any component&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Generate for each platform
&lt;/h2&gt;

&lt;p&gt;We give Style Dictionary the tokens + the target formats, and it generates the rest. The key point: &lt;strong&gt;ship idiomatic code per platform&lt;/strong&gt;, not raw JSON. An iOS dev wants typed Swift.&lt;/p&gt;

&lt;p&gt;We have 3 combinations (brand × theme) to generate, so we loop. &lt;code&gt;build.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;StyleDictionary&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;style-dictionary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;style-dictionary/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;combinations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brandA&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brandA&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brandB&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;platformsFor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;platforms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;css&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;transformGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;buildPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build/web/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.css`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css/variables&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;ios&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;transformGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ios-swift&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;buildPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build/ios/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.swift`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ios-swift/class.swift&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tokens&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;transformGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;compose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;buildPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build/android/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.kt`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;compose/object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                       &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tokens&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;packageName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;com.monorg.tokens&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;transformGroup&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;buildPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;build/json/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.json`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json/flat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;combinations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StyleDictionary&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// Source = the common layer (primitives) + this combination's semantic links.&lt;/span&gt;
    &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tokens/primitives.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`tokens/semantic.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.json`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;platforms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;platformsFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buildAllPlatforms&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node build.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there's the same decision, translated into each language. &lt;strong&gt;Web&lt;/strong&gt; (&lt;code&gt;build/web/brandA-light.css&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2563eb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-on-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-surface&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-on-surface&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#111827&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--space-4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--radius-md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;iOS&lt;/strong&gt; (&lt;code&gt;build/ios/brandA-light.swift&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;Tokens&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;colorPrimary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.145&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.388&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.922&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;alpha&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Android / Compose&lt;/strong&gt; (&lt;code&gt;build/android/brandB-light.kt&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.monorg.tokens&lt;/span&gt;
&lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;Tokens&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;colorPrimary&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xff059669&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// brandB → green&lt;/span&gt;
  &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;colorPrimaryHover&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;0xff047857&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One source, three languages, &lt;strong&gt;idiomatic&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — A component that consumes (and the magic of the switch)
&lt;/h2&gt;

&lt;p&gt;The component uses &lt;strong&gt;only&lt;/strong&gt; semantic tokens, no hard-coded colors. &lt;code&gt;demo/index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"theme"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"../build/web/brandA-light.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="nc"&gt;.btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color-on-primary&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--space-2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--space-4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--radius-sm&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.btn&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color-primary-hover&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"btn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Primary action&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;// The only switch: we swap the token stylesheet. The component does not change.&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;theme&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../build/web/brandA-dark.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change &lt;code&gt;brandA-light&lt;/code&gt; → &lt;code&gt;brandA-dark&lt;/code&gt; → &lt;code&gt;brandB-light&lt;/code&gt;: the button re-themes itself. &lt;strong&gt;Not a single line of the component moves.&lt;/strong&gt; That's the whole point of the semantic level.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5 — Test regressions (the indispensable safety net)
&lt;/h2&gt;

&lt;p&gt;In a system consumed everywhere, a silent regression spreads &lt;em&gt;everywhere&lt;/em&gt; at once. We add a net, with zero dependencies, using &lt;code&gt;node:test&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A deliberate choice: writing these tests in Gherkin&lt;/strong&gt; (&lt;code&gt;Feature&lt;/code&gt; / &lt;code&gt;Scenario&lt;/code&gt; / &lt;em&gt;Given / When / Then&lt;/em&gt;). Why? Because a design system is consumed as much by &lt;strong&gt;non-developers&lt;/strong&gt; (designers, PMs) as by devs. Phrased this way, the tests become &lt;strong&gt;documentation that reads like sentences&lt;/strong&gt;: "&lt;em&gt;Given&lt;/em&gt; brand A in dark, &lt;em&gt;when&lt;/em&gt; generated, &lt;em&gt;then&lt;/em&gt; primary points to blue 300". No need to read code to know what the system guarantees. &lt;code&gt;test/tokens.test.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;assert&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:assert/strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;readFileSync&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node:fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;combo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`../build/json/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;combo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.json`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Feature: semantic links resolve to the right primitives&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Scenario: the dark theme reuses the same semantic names&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Given brand A in dark, When generated, Then primary points to blue 300&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brandA-dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ColorPrimary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#60a5fa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ColorSurface&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#111827&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Scenario: switching brand is just re-wiring the links&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Given brand B in light, When generated, Then primary = green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brandB-light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ColorPrimary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#059669&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node build.ts &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; node &lt;span class="nt"&gt;--test&lt;/span&gt; &lt;span class="s2"&gt;"test/**/*.test.ts"&lt;/span&gt;
&lt;span class="c"&gt;# ✔ Feature: semantic links resolve to the right primitives&lt;/span&gt;
&lt;span class="c"&gt;#   ✔ Scenario: the dark theme reuses the same semantic names&lt;/span&gt;
&lt;span class="c"&gt;#   ✔ Scenario: switching brand is just re-wiring the links&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If someone breaks a primitive or a link, the test &lt;strong&gt;fails before&lt;/strong&gt; the regression reaches the products. The repo wires this into a &lt;strong&gt;GitHub Actions CI&lt;/strong&gt; that, on every push, builds all combinations, &lt;strong&gt;checks the multi-platform artifacts were actually generated&lt;/strong&gt;, and runs the tests — so a broken link never reaches &lt;code&gt;main&lt;/code&gt;. In production, you complement this with &lt;strong&gt;snapshot tests&lt;/strong&gt; on the generated files (any change to an output becomes explicit in review) and, on the component side, a &lt;strong&gt;Storybook&lt;/strong&gt; + &lt;strong&gt;automated visual review&lt;/strong&gt; (Chromatic-style).&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 — Assets (the real challenge: icons &amp;amp; fonts)
&lt;/h2&gt;

&lt;p&gt;Colors are the easy part. Where a design system earns its stripes is on &lt;strong&gt;assets&lt;/strong&gt;: an icon or a font must also start from a &lt;strong&gt;single source&lt;/strong&gt; and be translated into each platform's format.&lt;/p&gt;

&lt;p&gt;The most telling case: &lt;strong&gt;Android doesn't read SVG natively&lt;/strong&gt;, it needs a &lt;em&gt;Vector Drawable&lt;/em&gt; XML. So we write a small &lt;code&gt;SVG → Vector Drawable&lt;/code&gt; converter (excerpt):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;svgToVectorDrawable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[,&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/viewBox="&lt;/span&gt;&lt;span class="se"&gt;([\d&lt;/span&gt;&lt;span class="sr"&gt;.&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;-&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;"/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;svg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;matchAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&amp;lt;path&lt;/span&gt;&lt;span class="se"&gt;\b[^&lt;/span&gt;&lt;span class="sr"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="sr"&gt;d="&lt;/span&gt;&lt;span class="se"&gt;([^&lt;/span&gt;&lt;span class="sr"&gt;"&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;"&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&amp;gt;/gi&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fill&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/fill="&lt;/span&gt;&lt;span class="se"&gt;([^&lt;/span&gt;&lt;span class="sr"&gt;"&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;"/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[])[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;currentColor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fill&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;currentColor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#FF000000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`#FF&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`    &amp;lt;path android:fillColor="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" android:pathData="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;" /&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;dp" android:height="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;dp"
    android:viewportWidth="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" android:viewportHeight="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;
&amp;lt;/vector&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From a single &lt;code&gt;assets/icons/check.svg&lt;/code&gt;, the pipeline produces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web&lt;/strong&gt; → the SVG as-is + a JSON manifest;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;iOS&lt;/strong&gt; → a &lt;em&gt;type-safe&lt;/em&gt; &lt;code&gt;enum Icon&lt;/code&gt; (no more "magic strings") + the SVG;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android&lt;/strong&gt; → &lt;code&gt;ic_check.xml&lt;/code&gt; (Vector Drawable) + an &lt;code&gt;enum Icon&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same logic for the &lt;strong&gt;font&lt;/strong&gt;: one &lt;code&gt;Inter.ttf&lt;/code&gt; → &lt;code&gt;@font-face&lt;/code&gt; (web), &lt;code&gt;FontRegistrar.swift&lt;/code&gt; (iOS), &lt;code&gt;res/font/&lt;/code&gt; (Android). The full code is in the repo (&lt;code&gt;src/buildAssets.ts&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That's&lt;/em&gt; the difference between "a shared color file" and a real design system: &lt;strong&gt;the multi-platform asset chain.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7 — Distribute it like a real product
&lt;/h2&gt;

&lt;p&gt;A design system only has value if it's &lt;strong&gt;easy to consume&lt;/strong&gt;. Never ask people to copy files: publish to native package managers, and &lt;strong&gt;version with SemVer&lt;/strong&gt; (with &lt;code&gt;alpha / beta / rc / stable&lt;/code&gt; channels).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @monorg/design-tokens@1.2.0      &lt;span class="c"&gt;# web&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"monorg:design-tokens:1.2.0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// android (Maven)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Automate it via CI: a &lt;strong&gt;version tag&lt;/strong&gt; triggers a pipeline that &lt;em&gt;builds&lt;/em&gt; all formats and &lt;em&gt;publishes&lt;/em&gt; each package to its registry (npm / SPM / Maven). No manual step = no drift between the repo and what's shipped.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# pseudo-pipeline&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tag 'tokens-v*'&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;node build.ts&lt;/span&gt;
  &lt;span class="na"&gt;publish&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;npm&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;spm&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;maven&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;   &lt;span class="c1"&gt;# one job per registry&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The real win: each consumer pins ITS version
&lt;/h3&gt;

&lt;p&gt;This is the point people underestimate at first. Once tokens are published as versioned packages, &lt;strong&gt;each application picks the version it consumes&lt;/strong&gt; — and that's what makes the system usable at scale:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Total decoupling.&lt;/strong&gt; The design team can publish &lt;code&gt;1.3.0&lt;/code&gt; today without breaking anything: the iOS app stays on &lt;code&gt;1.2.0&lt;/code&gt; until it decides to bump. Nobody is forced to move at the same time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progressive rollout.&lt;/strong&gt; You test a new palette on &lt;strong&gt;one&lt;/strong&gt; product (which goes to &lt;code&gt;1.3.0-alpha.1&lt;/code&gt;) while the others stay stable. If it breaks, the blast radius is &lt;em&gt;one&lt;/em&gt; repo, not all of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproducible builds.&lt;/strong&gt; A lockfile pinned to &lt;code&gt;1.2.0&lt;/code&gt; produces &lt;em&gt;exactly&lt;/em&gt; the same rendering in six months. A "shared folder" that changes under your feet does not.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;History and rollback.&lt;/strong&gt; A visual regression in prod? Revert to the previous version in one line (&lt;code&gt;@1.1.0&lt;/code&gt;) while you fix it. No panicked hotfix across 6 codebases.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;design-tokens   v1.3.0  ← latest published
   ├── web app      "@monorg/design-tokens": "1.3.0"   (up to date)
   ├── iOS app      from: "1.2.0"                       (bumps when it wants)
   └── Android app  "monorg:design-tokens:1.2.0"         (same)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The design system becomes &lt;strong&gt;a dependency like any other&lt;/strong&gt;: you update it when you're ready, you read the CHANGELOG, you pin, you roll back. It's exactly this versioning mechanism that turns a "shared folder" into &lt;strong&gt;infrastructure&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;A design system is &lt;strong&gt;not a button library&lt;/strong&gt;. It's infrastructure, and its value is in the &lt;em&gt;chain&lt;/em&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A single source of truth&lt;/strong&gt;: the tokens, in neutral form.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Three levels&lt;/strong&gt;: primitives → semantic → component. That's what makes multi-brand manageable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A generation&lt;/strong&gt; to idiomatic code per platform (Style Dictionary).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A distribution&lt;/strong&gt; versioned with SemVer, via native package managers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests&lt;/strong&gt; (Gherkin + snapshots + visual review) to change without fear — and that document the system, even for non-devs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The full POC code is here → &lt;strong&gt;&lt;a href="https://github.com/ibrahimdans/design-system-poc" rel="noopener noreferrer"&gt;github.com/ibrahimdans/design-system-poc&lt;/a&gt;&lt;/strong&gt;. Clone it, &lt;code&gt;npm install&lt;/code&gt;, &lt;code&gt;npm run demo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The real question isn't &lt;em&gt;"which components should go in my design system?"&lt;/em&gt;. It's:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;"Do my design decisions have a single source of truth, or are they copied by hand?"&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Start there.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Unifying several products or several platforms? I design design systems that scale. Let's talk on &lt;a href="https://linkedin.com/in/ibrahimadansoko" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>styledictionary</category>
      <category>tutorial</category>
      <category>node</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Principles I Code By: Small Rules, Big Difference</title>
      <dc:creator>Ibrahima D.</dc:creator>
      <pubDate>Sat, 06 Jun 2026 16:09:32 +0000</pubDate>
      <link>https://dev.to/ibrahimdans/the-principles-i-code-by-small-rules-big-difference-5d6a</link>
      <guid>https://dev.to/ibrahimdans/the-principles-i-code-by-small-rules-big-difference-5d6a</guid>
      <description>&lt;p&gt;&lt;strong&gt;Frameworks come and go. Principles stay.&lt;/strong&gt; ✨&lt;/p&gt;

&lt;p&gt;After a few years of writing software — from MVPs built from scratch 🚀 to legacy systems nobody dared to touch 👻 — I've come to realize something: the developers I admire most aren't the ones who know the most frameworks. They're the ones who follow a few simple principles, consistently, on every line they write.&lt;/p&gt;

&lt;p&gt;Over time, I've collected my own set of principles. They act like a compass 🧭: whenever I'm unsure how to approach a problem, I come back to them. None of them are mine — they've been shaped by people much smarter than me — but together they form the way I work. Let me walk you through each one, with examples from real life. 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Make it work, make it right, make it fast
&lt;/h2&gt;

&lt;p&gt;This one, from &lt;strong&gt;Kent Beck&lt;/strong&gt;, is the backbone of everything else. It's an order of priorities, and the order matters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;✅ &lt;strong&gt;Make it work&lt;/strong&gt; — first, get a working solution. Don't optimize, don't over-engineer. Just solve the problem.&lt;/li&gt;
&lt;li&gt;🧹 &lt;strong&gt;Make it right&lt;/strong&gt; — now refactor. Clean names, clear structure, tests. Make it readable for the next person (often your future self).&lt;/li&gt;
&lt;li&gt;🏎️ &lt;strong&gt;Make it fast&lt;/strong&gt; — only then, &lt;em&gt;if needed&lt;/em&gt;, optimize for performance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;An example 💡.&lt;/strong&gt; You need to display a list of users. The trap is to immediately think about caching, pagination, and database indexes. Don't. First, fetch the list and render it (&lt;em&gt;it works&lt;/em&gt;). Then extract a clean component and add a test (&lt;em&gt;it's right&lt;/em&gt;). Then, &lt;em&gt;only if the page is actually slow&lt;/em&gt;, add caching (&lt;em&gt;it's fast&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Most performance problems we obsess over never materialize. Respect the order, and you'll move faster overall. 🎯&lt;/p&gt;

&lt;h2&gt;
  
  
  🔮 YAGNI — You Aren't Gonna Need It
&lt;/h2&gt;

&lt;p&gt;We love to build for a future that rarely comes. 🔭 &lt;em&gt;"We might need this option later"&lt;/em&gt;, &lt;em&gt;"let's make it configurable just in case"&lt;/em&gt;... and we end up maintaining code nobody uses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An example 💡.&lt;/strong&gt; You're asked to export data as CSV. You think: "I'll build a generic exporter that also supports JSON, XML, and PDF, so we're ready for anything." Six months later, only CSV is used — but you're still maintaining (and debugging 🐛) three formats nobody asked for.&lt;/p&gt;

&lt;p&gt;YAGNI is a reminder: &lt;strong&gt;build for the need you have today, not the one you imagine for tomorrow.&lt;/strong&gt; ⏳ When tomorrow actually arrives, you'll have better information to build the right thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎲 The Principle of Least Surprise
&lt;/h2&gt;

&lt;p&gt;Code should behave the way the reader &lt;em&gt;expects&lt;/em&gt; it to. The best code is boring: when someone opens your file, nothing makes them go &lt;em&gt;"wait, what?"&lt;/em&gt; 😵 Surprise is where bugs hide.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An example 💡.&lt;/strong&gt; A function called &lt;code&gt;getUser()&lt;/code&gt; that &lt;em&gt;also&lt;/em&gt; silently updates the last-login timestamp in the database. The name promises a read; the body does a write. Six months later, someone calls it in a loop to display names — and accidentally hammers the database. The code wasn't complex. It was &lt;em&gt;surprising&lt;/em&gt;. A function should do what its name says, nothing more.&lt;/p&gt;

&lt;p&gt;Here's a subtle one — and it sets up the next principle nicely: &lt;em&gt;predictable&lt;/em&gt; often wins over &lt;em&gt;simple&lt;/em&gt;. Sometimes slightly more verbose, "boring" code that follows the conventions of your codebase beats a clever one-liner that makes the next reader stop and squint. Be the developer whose code holds no surprises. 🧘&lt;/p&gt;

&lt;h2&gt;
  
  
  ✂️ KISS — Keep It Simple
&lt;/h2&gt;

&lt;p&gt;The simplest solution that solves the problem is almost always the best one. Complexity is easy to add and very hard to remove. 🧨&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An example 💡.&lt;/strong&gt; I've seen a single function grow to 200 lines because it tried to handle every imaginable case with a pile of flags: &lt;code&gt;processData(data, true, false, true)&lt;/code&gt;. 😵‍💫 Nobody could read it. Split into three small, well-named functions, the same logic became obvious at a glance.&lt;/p&gt;

&lt;p&gt;Before writing a clever abstraction, ask yourself: &lt;em&gt;do I really need this, or am I just showing off?&lt;/em&gt; 🤔 Simple code is code your teammates can read, debug, and change without fear. That's worth more than cleverness — but remember the previous principle: if "simple" means "surprising," go for predictable instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  ♻️ DRY — Don't Repeat Yourself
&lt;/h2&gt;

&lt;p&gt;Every piece of knowledge should have a single source of truth in your codebase. When the same logic lives in three places, fixing a bug means remembering all three — and you never do.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An example 💡.&lt;/strong&gt; A password validation rule (8 characters, one uppercase, one digit) copy-pasted into the signup form, the reset form, and the back-end. The day the rule changes, you'll fix two of them and ship the bug in the third. 😬 Extract it once, use it everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But be careful ⚠️&lt;/strong&gt; — don't apply DRY too early. Two pieces of code that &lt;em&gt;look&lt;/em&gt; similar today might evolve in different directions tomorrow. Forcing them into one abstraction creates a tangled mess. As the saying goes: &lt;em&gt;duplication is cheaper than the wrong abstraction.&lt;/em&gt; Wait until you see the pattern repeat a third time before extracting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧱 SOLID — Five Letters for Maintainable Code
&lt;/h2&gt;

&lt;p&gt;SOLID is a set of five principles for object-oriented design. People recite them like a spell, but each one solves a very concrete pain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;S — Single Responsibility.&lt;/strong&gt; A class (or function) should have one reason to change. A &lt;code&gt;User&lt;/code&gt; class that handles authentication &lt;em&gt;and&lt;/em&gt; sends emails &lt;em&gt;and&lt;/em&gt; formats invoices will break in three different ways. Split responsibilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O — Open/Closed.&lt;/strong&gt; Open for extension, closed for modification. Adding a new payment method shouldn't mean editing a giant &lt;code&gt;if/else&lt;/code&gt;. You should be able to &lt;em&gt;plug in&lt;/em&gt; the new case without touching the existing, tested code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;L — Liskov Substitution.&lt;/strong&gt; A subtype must work anywhere its parent is expected. If your &lt;code&gt;Square&lt;/code&gt; extends &lt;code&gt;Rectangle&lt;/code&gt; but breaks when you set width and height independently, your hierarchy is lying to you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I — Interface Segregation.&lt;/strong&gt; Many small, focused interfaces beat one giant one. Don't force a class to implement methods it doesn't need just because they live in the same interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;D — Dependency Inversion.&lt;/strong&gt; Depend on abstractions, not concrete details. Your business logic shouldn't know &lt;em&gt;which&lt;/em&gt; database you use. Pass it an interface, and you can swap the implementation (or mock it in tests) freely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don't need to recite them. You need to feel them: code that's &lt;strong&gt;easy to extend and hard to break.&lt;/strong&gt; 💪&lt;/p&gt;

&lt;h2&gt;
  
  
  👣 Baby Steps — Small, Validated Increments
&lt;/h2&gt;

&lt;p&gt;Big changes are scary because they fail in big, mysterious ways. Small changes fail small, and they tell you exactly what went wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An example 💡.&lt;/strong&gt; Instead of writing 300 lines and running everything at the end (then spending an hour figuring out which part broke), I write a few lines, run the tests, commit, and repeat. When something fails, I know it's in the last tiny change — not somewhere in 300 lines. And because I commit often, &lt;code&gt;git bisect&lt;/code&gt; becomes a superpower. 🦸&lt;/p&gt;

&lt;p&gt;Progress made of tiny, reversible steps is faster than it looks — and far less stressful. 😌&lt;/p&gt;

&lt;h2&gt;
  
  
  🌳 The Mikado Method — Taming the Big Refactor
&lt;/h2&gt;

&lt;p&gt;Sometimes a change looks simple, then you pull the thread and the whole sweater unravels. 🧶 The &lt;strong&gt;Mikado Method&lt;/strong&gt; is how I handle that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An example 💡.&lt;/strong&gt; You want to upgrade a library. You change it — and 12 files break. The naive approach is to fix them all at once and pray. 😅 The Mikado approach: try the change, &lt;em&gt;see&lt;/em&gt; what breaks, write down the prerequisites, then &lt;strong&gt;revert&lt;/strong&gt;. Now tackle one prerequisite at a time, each as its own small, safe commit. Once the groundwork is done, the original change becomes trivial.&lt;/p&gt;

&lt;p&gt;The result: no more half-finished refactors stuck in a branch for three weeks. You always have working code, and a clear map of what's left. 🗺️&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 How they fit together
&lt;/h2&gt;

&lt;p&gt;None of these principles work alone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🪶 &lt;strong&gt;KISS&lt;/strong&gt;, &lt;strong&gt;YAGNI&lt;/strong&gt; and &lt;strong&gt;Least Surprise&lt;/strong&gt; keep me from building too much — and from building it weird.&lt;/li&gt;
&lt;li&gt;🛠️ &lt;strong&gt;DRY&lt;/strong&gt; and &lt;strong&gt;SOLID&lt;/strong&gt; keep what I build maintainable.&lt;/li&gt;
&lt;li&gt;🛡️ &lt;strong&gt;Baby Steps&lt;/strong&gt; and &lt;strong&gt;Mikado&lt;/strong&gt; keep me safe when I change existing code.&lt;/li&gt;
&lt;li&gt;🧭 And &lt;strong&gt;"make it work, make it right, make it fast"&lt;/strong&gt; sets the order for all of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But here's the uncomfortable truth nobody tells you when you first learn these: &lt;strong&gt;principles contradict each other.&lt;/strong&gt; 💥 YAGNI says &lt;em&gt;don't build it&lt;/em&gt;, while SOLID says &lt;em&gt;add this layer of abstraction&lt;/em&gt;. DRY says &lt;em&gt;extract the duplicate&lt;/em&gt;, while Least Surprise says &lt;em&gt;keep it consistent and obvious&lt;/em&gt;. So which one wins?&lt;/p&gt;

&lt;p&gt;The trick is to treat them as a &lt;strong&gt;hierarchy, not a checklist.&lt;/strong&gt; 🏛️ The foundational ones come first, and a "higher" principle is only allowed to apply when it doesn't break a "lower" one. Roughly: &lt;em&gt;make it work&lt;/em&gt; → &lt;em&gt;YAGNI&lt;/em&gt; → &lt;em&gt;least surprise&lt;/em&gt; → &lt;em&gt;KISS&lt;/em&gt; → &lt;em&gt;DRY&lt;/em&gt; → &lt;em&gt;SOLID&lt;/em&gt; → and &lt;em&gt;make it fast&lt;/em&gt; dead last. When two principles clash, the more foundational one wins. That's how you stop arguing in circles in code review.&lt;/p&gt;

&lt;p&gt;They're not rules I follow blindly — every one of them has a &lt;em&gt;"but"&lt;/em&gt; attached, as you've seen. They're a starting point, a default. The judgment of when to bend them — and which one outranks which — comes with experience.&lt;/p&gt;

&lt;p&gt;So next time you're staring at a problem, unsure where to start, ask yourself the simplest question:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;"What's the smallest, simplest thing that makes this work?"&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Start there. Your code, your teammates, and your future self will thank you. 🙌&lt;/p&gt;




&lt;p&gt;These are &lt;em&gt;my&lt;/em&gt; principles — but I'm always looking to sharpen my compass. 🧭&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about you?&lt;/strong&gt; Which principle has saved you the most pain? Is there a rule you swear by that I didn't mention here? Or maybe one of these you've learned to &lt;em&gt;break&lt;/em&gt; on purpose?&lt;/p&gt;

&lt;p&gt;👇 &lt;strong&gt;Drop your favorite tip in the comments&lt;/strong&gt; — I read every one, and I'd love to learn from yours. And if this article resonated with you, a ❤️ or a 🔖 helps it reach another dev who needs it.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀 &lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>cleancode</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to use two instances of Claude Code</title>
      <dc:creator>Ibrahima D.</dc:creator>
      <pubDate>Tue, 19 Aug 2025 15:24:44 +0000</pubDate>
      <link>https://dev.to/ibrahimdans/how-to-use-two-instances-of-claude-code-2nae</link>
      <guid>https://dev.to/ibrahimdans/how-to-use-two-instances-of-claude-code-2nae</guid>
      <description>&lt;p&gt;&lt;strong&gt; You have reached the limit for Claude Code &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F288ry0oj49fc9yg4aooj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F288ry0oj49fc9yg4aooj.png" alt=" " width="800" height="38"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's quite frustrating, especially since it often happens when our treatment isn't finished.&lt;br&gt;
It's not ideal to have two instances of Claude, because it means paying for Claude Pro twice, but it's cheaper than having Claude Max, which costs over €100.&lt;/p&gt;

&lt;p&gt;First, at the root of your account, create a new folder that will hold your Claude configurations, credentials, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpna116amqbdoptd8ptzv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpna116amqbdoptd8ptzv.png" alt=" " width="191" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have specific configurations such as commands, don't forget to copy them. That's what I do when I activate another instance of Claude.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cp -R .claude .claude-2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;in zshrc &lt;code&gt;$HOME/.zshrc|.bashrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cc() {
 claude
}

ccp() {

CLAUDE_CONFIG_DIR=~/.claude-2 claude

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you just need to launch &lt;strong&gt;cc&lt;/strong&gt; for claude or &lt;strong&gt; ccp  for claude-2.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Note: &lt;strong&gt;cc&lt;/strong&gt; and &lt;strong&gt;ccp&lt;/strong&gt; are arbitrary you can call them whatever you want.&lt;/p&gt;

&lt;p&gt;Enjoy &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9l5gkm9tirlo25v5hc6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9l5gkm9tirlo25v5hc6e.png" alt=" " width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Essential Code Review Terms Every Developer Should Know</title>
      <dc:creator>Ibrahima D.</dc:creator>
      <pubDate>Mon, 07 Jul 2025 09:12:09 +0000</pubDate>
      <link>https://dev.to/ibrahimdans/essential-code-review-terms-every-developer-should-know-2dp6</link>
      <guid>https://dev.to/ibrahimdans/essential-code-review-terms-every-developer-should-know-2dp6</guid>
      <description>&lt;p&gt;When I first started out in this profession, I would often come across certain terms and acronyms in code reviews and team discussions, and I always wondered what they meant. If you’re new to software development or just want a refresher, here’s a handy list that might help you navigate those conversations more confidently.&lt;/p&gt;

&lt;p&gt;Common Terms and Acronyms&lt;br&gt;
&lt;strong&gt;WIP&lt;/strong&gt; (Work In Progress): Indicates that the work or pull request is not finished yet and is not ready for a full review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LGTM&lt;/strong&gt; (Looks Good To Me): The proposed code looks correct and can be merged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NIT&lt;/strong&gt; (Nitpick): A minor suggestion or remark, often about style or readability, with no functional impact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ACK&lt;/strong&gt; (Acknowledge): Confirms that a comment has been read and considered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PTAL&lt;/strong&gt; (Please Take A Look): A request to review or re-review the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RFC&lt;/strong&gt; (Request For Comments): An invitation for feedback or opinions on a proposal or change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMO/IMHO&lt;/strong&gt; (In My [Humble] Opinion): Indicates that what follows is a personal opinion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blocking&lt;/strong&gt;: A comment or issue that must be addressed before the code can be merged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Non-blocking&lt;/strong&gt;: A suggestion or remark that does not prevent the code from being merged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ship It&lt;/strong&gt;: Informal way of saying the code is ready to be delivered or merged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stale&lt;/strong&gt;: A review or pull request that hasn’t seen activity in a long time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-review&lt;/strong&gt;: Reviewing your own code before submitting it to others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refactor&lt;/strong&gt;: Rewriting code to improve its structure or readability without changing its functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Patch&lt;/strong&gt;: A software fix or update.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hotfix&lt;/strong&gt;: A quick fix for a critical bug, usually deployed urgently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DRY&lt;/strong&gt; (Don’t Repeat Yourself): Principle to avoid code duplication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bump&lt;/strong&gt;: To increase or update a version number, or to make a small improvement or fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chore&lt;/strong&gt;: A technical or maintenance task that doesn’t add a new user-facing feature, but is necessary for the health of the project (e.g., code cleanup, updating dependencies, configuring tools).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FYI&lt;/strong&gt; (For Your Information): Sharing information without expecting an immediate response or action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TBR&lt;/strong&gt; (To Be Reviewed): Indicates that a piece of code or change is waiting for review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dead code&lt;/strong&gt;: Unused or obsolete code that should be removed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Needs Rebase&lt;/strong&gt;: The branch needs to be updated to resolve conflicts or incorporate the latest changes from the main branch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outdated&lt;/strong&gt;: A comment made on an older version of the code, often after a rebase or new commit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TBD&lt;/strong&gt; (To Be Determined/Defined): Something that still needs to be specified or decided.&lt;/p&gt;

&lt;p&gt;If you know more terms or acronyms that are commonly used in code reviews, feel free to share them in the comments! This list is not exhaustive, and your input can help others in the community. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8fy543e9m32kkikg57b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu8fy543e9m32kkikg57b.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>development</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Enhancing Testability with Dynamic Data-testid Attributes</title>
      <dc:creator>Ibrahima D.</dc:creator>
      <pubDate>Thu, 28 Mar 2024 14:21:39 +0000</pubDate>
      <link>https://dev.to/ibrahimdans/enhancing-testability-with-dynamic-data-testid-attributes-4407</link>
      <guid>https://dev.to/ibrahimdans/enhancing-testability-with-dynamic-data-testid-attributes-4407</guid>
      <description>&lt;p&gt;We've all been faced with the challenge of choosing a better test ID for our component at some point. Why not leverage the logic we already use for CSS, like BEM (Block Element Modifier)? What is the best solution for achieving consistent and logical IDs across the board? What are the existing best practices?&lt;/p&gt;

&lt;p&gt;✅ The Solution:&lt;br&gt;
The best solution I've found with React is to create a custom hook that generates an ID, making it easier to locate them in our tests.&lt;/p&gt;

&lt;p&gt;📚 Code Examples:&lt;/p&gt;

&lt;p&gt;Create a custom hook useTestIdGenerator.ts:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqnvgc5lhoukytfjaamb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqnvgc5lhoukytfjaamb.png" alt=" " width="800" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the custom hook in your grid component:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwpfp2r0u86mian29dbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwpfp2r0u86mian29dbh.png" alt=" " width="800" height="652"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, each element in your grid has unique "data-testid" attributes!&lt;/p&gt;

&lt;p&gt;This approach greatly facilitates testing of dynamic components while maintaining the cleanliness and maintainability of your code. 🔥&lt;/p&gt;

&lt;p&gt;An example test using this unique attribute:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokwy6vh5loza5pgpcehp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokwy6vh5loza5pgpcehp.png" alt=" " width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't hesitate If you have another even better solution, to suggest it in the comments.&lt;/p&gt;

</description>
      <category>react</category>
      <category>testing</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The boy scout rule : Small Steps, Big Impact</title>
      <dc:creator>Ibrahima D.</dc:creator>
      <pubDate>Mon, 04 Sep 2023 10:01:31 +0000</pubDate>
      <link>https://dev.to/ibrahimdans/the-boy-scout-rule-small-steps-big-impact-1dp6</link>
      <guid>https://dev.to/ibrahimdans/the-boy-scout-rule-small-steps-big-impact-1dp6</guid>
      <description>&lt;p&gt;In his book 'Clean Code,' &lt;strong&gt;Robert C. Martin&lt;/strong&gt; introduces us to an essential principle for writing beautiful code, the famous Boy Scout Rule, which can be summed up in one sentence: 'Always leave a place in a better state than you found it.'&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps8rj3njw0f26s8tzg2i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps8rj3njw0f26s8tzg2i.jpg" alt=" " width="640" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As developers, we are constantly faced with challenges to produce clean, readable, and maintainable code. One of the simplest yet most powerful methods to achieve this goal is the Boy Scout Rule. Inspired by the idea of leaving the environment in a better state than we found it, this rule can have a significant impact on the quality of our code. In this article, we will explore this concept and discover how it can enhance our development process&lt;/p&gt;

&lt;p&gt;The Boy Scout Rule, popularized by software engineering veteran Robert C. Martin, encourages us to improve the code with every change we make, even if that change is not directly related to our current task. This can include minor adjustments such as renaming variables for clarity, adding comments to explain complex parts of the code, or reorganizing sections for better readability.&lt;/p&gt;

&lt;p&gt;The Benefits of Following the Rule&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cleaner Code&lt;/strong&gt;: By adopting this rule, we ensure that our code remains consistently clean and organized. The cumulative effect of small improvements over time contributes to overall quality maintenance.&lt;/p&gt;

&lt;p&gt;Ease of Maintenance: Well-maintained code is easier to understand and modify. Future development teams will appreciate code that reads like a well-written book.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reducing Technical Debt&lt;/strong&gt;: By preventing the accumulation of poor code, we avoid technical debt, allowing development to proceed smoothly without being hindered by quality issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Apply the Boy Scout Rule&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be Conscious&lt;/strong&gt;: Every time you modify a part of the code, be mindful of opportunities for improvement. Ask yourself, "How can I leave this part of the code in a better state?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prioritize&lt;/strong&gt;: Not all improvements are equal. Focus on changes that will have the most impact on code readability, maintainability, and clarity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Communicate&lt;/strong&gt;: Share the Boy Scout Rule with your colleagues. Encourage a development culture where a commitment to quality is valued.&lt;/p&gt;

&lt;p&gt;The Boy Scout Rule is a simple yet effective approach to ensuring the ongoing quality of our code. By incorporating this philosophy into our development process, we contribute to an environment where code respect and a continuous improvement mindset are at the core of our work. So, the next time you make a change, ask yourself, &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;'Am I leaving the code in a better state than I found it?'&lt;/strong&gt;&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Your code, your colleagues, and your future self will thank you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5fz7p8sic5xl3rzmjqr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv5fz7p8sic5xl3rzmjqr.png" alt=" " width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>11 Pieces of Advice I Wish I Had Known as a Junior Developer</title>
      <dc:creator>Ibrahima D.</dc:creator>
      <pubDate>Wed, 16 Aug 2023 10:41:40 +0000</pubDate>
      <link>https://dev.to/ibrahimdans/11-pieces-of-advice-i-wish-i-had-known-as-a-junior-developer-2o7e</link>
      <guid>https://dev.to/ibrahimdans/11-pieces-of-advice-i-wish-i-had-known-as-a-junior-developer-2o7e</guid>
      <description>&lt;p&gt;Being a &lt;strong&gt;junior developer&lt;/strong&gt; is an exciting stage, but it's often filled with challenges and learning experiences. Looking back, many developers realize that there were several things they would have liked to know at the beginning of their careers. This article delves into the valuable lessons and advice that I would have wished to receive when starting out in the field.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Don't Neglect the Basics !!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the most common mistakes made by junior developers is to focus solely on memorizing syntax and using ready-made solutions. In reality, understanding the fundamental concepts of programming and specific languages is essential. This enables more effective problem-solving, adaptation of solutions to needs, and building a solid foundation for further development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Read the Documentation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reading, re-reading, and reading documentation again is often underestimated, but it can make all the difference in the development process. Junior developers should learn to read and create accurate documentation from the start. This facilitates collaboration with other team members, understanding libraries and frameworks, and contributes to quick problem resolution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Learn How to Learn&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The development industry evolves rapidly with new technologies and emerging best practices constantly. Developers should become familiar with the idea that learning never stops. Participating in online courses, following relevant blogs, and working on personal projects are all ways to stay updated and continue evolving.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Code Simply, Then Format the Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's easy to fall into the trap of wanting to write perfect code from the start. However, it's more important to focus on efficient problem-solving. Developers should learn to iterate, test their ideas quickly, and improve gradually. Perfection comes with experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Don't Hesitate to Ask Questions and Seek Help&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Development isn't limited to just programming. Communication with team members, clients, and stakeholders is crucial for understanding needs, sharing ideas, and solving problems. Developers should cultivate their communication skills to become valuable team members.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Don't Fear Failure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Making mistakes is part of learning, so don't be afraid of making them. Even great software developers have been fired, made mistakes, and felt down, but what makes them great is that they rise and learn from their mistakes. Don't be discouraged by errors or bugs; use them as learning and growth opportunities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Contribute to Open Source Software&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You'll learn a lot by contributing to an open-source project, so by helping the community, you're helping yourself, and maintainers are happy. Start small and learn about the project; begin with a framework/tool you use. There are many ways to contribute to open-source projects, such as reporting a bug, reproducing the bug, and writing code to fix a bug or implement a new feature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Be Open to Feedback and Criticism&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Receiving constructive feedback on your code is a chance to learn and improve. Be open to critiques and consider them as opportunities for growth. Practicing egoless programming can be beneficial.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Manage Your Time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Development can be time-intensive. Learn to manage your time by planning, setting priorities, and avoiding getting overwhelmed by secondary tasks. The day you're satisfied with your development is the day you'll no longer grow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;10. Version Your Code (GitHub, GitLab, Bitbucket ...)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use a version control system like Git from the start. This allows you to track the evolution of your code, collaborate more effectively with other developers, and revert changes if necessary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11. Enjoy the Journey&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Taking breaks and vacations is essential to maintain a healthy balance between work and personal life. Schedule short, regular breaks throughout the day to rest your mind. Techniques like the Pomodoro technique recommend working for about 25 minutes and then taking a 5-minute break. Use this time to stand up, stretch, take deep breaths, or simply step away from your screen.&lt;/p&gt;

&lt;p&gt;Don't underestimate the importance of vacations. Plan your time off in advance and make sure to adhere to it. When you go on vacation, truly disconnect from work. Avoid checking your work emails or thinking about ongoing projects. Allow yourself the necessary time to rest, relax, and recharge.&lt;/p&gt;

&lt;p&gt;Regardless of the experience gained over the years, being junior or senior isn't determined by time alone, but by the level of professionalism one achieves. Each day is an opportunity to continue learning, growing, and refining one's skills. This mindset enables me not only to embrace new technologies and tackle challenges but also to stay connected to the very essence of programming – a constant quest for improvement and understanding. Recognizing that development is a perpetually evolving field, I remain linked to its ever-changing dynamics.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Egoless Programming</title>
      <dc:creator>Ibrahima D.</dc:creator>
      <pubDate>Thu, 10 Aug 2023 12:21:55 +0000</pubDate>
      <link>https://dev.to/ibrahimdans/egoless-programming-1h9o</link>
      <guid>https://dev.to/ibrahimdans/egoless-programming-1h9o</guid>
      <description>&lt;p&gt;In the dynamic landscape of software development, a transformative concept is gaining prominence: "Egoless Programming." Rooted in collaboration and humility, this approach transcends individual ego to prioritize collective success. This article delves into the tenets of egoless programming, its impact on project quality, and its role in cultivating a harmonious development environment. A fresh perspective that could steer developers toward more efficient and fulfilling horizons.&lt;/p&gt;

&lt;p&gt;Egoless programming," also known as "programming without ego" in French, is a concept in the field of computer programming that encourages developers to embrace a humble and collaborative approach when creating software. The fundamental idea behind egoless programming is for developers to set aside their ego, biases, and personal desires in order to work together constructively and produce high-quality code.&lt;/p&gt;

&lt;p&gt;The key principles of egoless programming include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Focus on Results, Not Individuals&lt;/strong&gt;: Emphasis is placed on achieving project objectives rather than seeking personal credit or recognition. Programmers prioritize what's best for the software and its users, rather than their own glory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Embrace Constructive Criticism&lt;/strong&gt;: Programmers should be open to feedback and suggestions from peers. They should be willing to challenge their own code and make improvements based on received feedback.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Team Collaboration&lt;/strong&gt;: Egoless programming promotes effective collaboration and communication among team members. Programmers should be ready to share knowledge and learn from others, rather than monopolizing expertise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Continuous Learning&lt;/strong&gt;: Programmers acknowledge that there's always something new to learn and discover. They should be open to continuous learning and skill improvement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minimize Code Ownership&lt;/strong&gt;: Instead of clinging to specific code as if it were their exclusive creation, programmers should encourage code sharing and collective improvement.&lt;/p&gt;

&lt;p&gt;Egoless programming can contribute to code quality enhancement, reduce conflicts within the development team, and foster a more positive and collaborative work environment. Ultimately, the focus is on creating high-quality software rather than individual programmer ego.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
