Advanced (Aktualisiert: 22.7.2026)

Designsystem mit Claude Code aufbauen: Design Tokens, Storybook und CI

Design Tokens, React-Komponenten, Storybook, Barrierefreiheit und CI mit Claude Code sicher einführen.

Designsystem mit Claude Code aufbauen: Design Tokens, Storybook und CI

Wenn aus fünf Buttons plötzlich fünfzig Sonderfälle werden

Ein Team beginnt meist harmlos: Ein Button wird kopiert, für die nächste Seite leicht angepasst und später noch einmal in einer anderen Farbe gebaut. Nach einigen Monaten unterscheiden sich Fokusrahmen, Abstände, Ladezustände und Fehlermeldungen. Niemand weiß mehr, welche Variante verbindlich ist. Eine kleine Farbänderung zieht sich dann durch Dutzende Dateien und beschädigt im schlimmsten Fall wichtige Produktseiten.

Ein Designsystem löst dieses Problem nicht durch eine möglichst große Komponentengalerie. Es schafft einen überprüfbaren Ablauf für Farben, Abstände, Typografie, Zustände, Freigaben und Tests. Claude Code kann dabei das bestehende Repository untersuchen, zusammengehörige Dateien ändern, Storybook und Tests ausführen und den Diff erläutern. Produktentscheidungen, Markenbedeutung und die abschließende Prüfung der Barrierefreiheit bleiben jedoch beim Menschen.

Dieser Leitfaden führt von Design Tokens über typisierte React-Komponenten bis zu Storybook, Accessibility- und visuellen Prüfungen in CI. Außerdem zeigt er eine realistische Grenze für Figma-Integrationen und erklärt, wie klein ein Auftrag an Claude Code sein sollte.

Vertiefende Anleitungen finden Sie unter Design Tokens mit Claude Code verwalten, Storybook mit Claude Code entwickeln und Barrierefreiheit mit Claude Code prüfen.

Die wichtigsten Punkte

  • tokens.json ist der überprüfbare Vertrag im Code; Figma liefert Entwurfs- und Review-Eingaben.
  • Claude Code bearbeitet klar begrenzte Dateien und führt reproduzierbare Prüfungen aus. Menschen entscheiden über Semantik, Marke und Freigabe.
  • Für Vite-basierte Storybook-Projekte ist 2026 @storybook/addon-vitest mit vitest --project=storybook der empfohlene Weg.
  • Komponenten werden einzeln migriert. Eine große automatische Umstellung erzeugt einen kaum prüfbaren Diff.
  • Automatisierte a11y-Prüfungen finden strukturelle Fehler, ersetzen aber weder Tastatur- noch Screenreader-Tests.

Zielarchitektur: ein Vertrag vom Token bis zur CI

Die zentrale Quelle in diesem Ablauf ist tokens.json. Figma bleibt für die Gestaltung unverzichtbar, doch der Code benötigt einen versionierbaren Vertrag, den ein Pull Request sichtbar macht und CI prüfen kann.

flowchart LR
  Figma["Figma Variables"]
  Tokens["tokens.json"]
  Build["token build script"]
  CSS["CSS variables"]
  TS["TypeScript token map"]
  Components["React components"]
  Storybook["Storybook stories"]
  CI["Visual and a11y CI"]

  Figma -->|review input| Tokens
  Tokens --> Build
  Build --> CSS
  Build --> TS
  CSS --> Components
  TS --> Components
  Components --> Storybook
  Storybook --> CI

Design Tokens sind benannte Designentscheidungen, die als Daten gespeichert werden: Farben, Abstände, Radien, Typografie und Komponentenzustände. Ein Button sollte deshalb nicht direkt von #2563eb abhängen. Ein semantischer Name wie action.background.primary erklärt, wofür der Wert verwendet wird, und erlaubt spätere Markenänderungen ohne Suchen und Ersetzen.

Aktuelle Primärquellen sind das Format der Design Tokens Community Group, die Claude-Code-Dokumentation, die Sicherheitshinweise für Claude Code, das Storybook Vitest addon, Accessibility-Tests in Storybook, visuelle Tests in Storybook und die Figma REST API.

Was Claude Code übernimmt und was Menschen entscheiden

Ein vager Auftrag wie „Baue ein Designsystem“ lässt zu viele Entscheidungen offen und erzeugt leicht einen großen, schwer prüfbaren Diff. Ein begrenzter Auftrag wie „Migriere nur Button, behalte die öffentliche API bei, ergänze Storybook-Zustände und führe a11y-Tests aus“ ist nachvollziehbar und bei Problemen rückgängig zu machen.

ArbeitsbereichGeeigneter Auftrag an Claude CodeEntscheidung des Menschen
TokensWiederholte Farben und Abstände im CSS erfassenMarkenbedeutung und Token-Namen festlegen
KomponentenTypisierte Grundbausteine wie Button, Input und Alert implementierenÖffentliche API und Produktsemantik freigeben
StorybookVarianten, Zustände und Interaction Stories ergänzenRelevante Zustände echter Arbeitsabläufe auswählen
BarrierefreiheitFehlende Labels, Fokusprobleme und axe-Verstöße findenScreenreader-Verständlichkeit und UX abschließend beurteilen
CIVisuelle und a11y-Prüfungen in Pull Requests einbauenBlockierungsregeln und Ausnahmeprozess definieren

Geben Sie Claude Code vor jeder Änderung eine kurze Projektregel. Der folgende Prompt ist bewusst auf überprüfbare Dateibereiche und Befehle begrenzt:

Regeln für die Designsystem-Aufgabe:
- Bearbeite ausschließlich src/components, src/styles, .storybook, tests, scripts und tokens.json.
- Ändere keine Markenfarben, ohne alte und neue Token-Namen aufzulisten.
- Jede neue Komponente benötigt TypeScript-Props, Tastaturverhalten, Storybook-Stories und Hinweise zur Barrierefreiheit.
- Führe npm run tokens:build, npm run test:storybook -- --run, npm run build-storybook und npm run test:visual aus, bevor du das Ergebnis meldest.
- Wenn sich das Fokusverhalten ändert, nenne die manuellen Prüfschritte.

Auch Sicherheit gehört zu diesem Ablauf. Figma-Zugriffstoken, npm-Token, CI-Geheimnisse und private Kundenscreenshots gehören weder in Prompts noch in Stories oder Logs. Halten Sie die Claude-Code-Berechtigungen eng, prüfen Sie Befehle vor der Freigabe und behandeln Sie große Snapshot-Änderungen als menschlich zu genehmigende Änderungen.

Minimale Einrichtung mit dem aktuellen Storybook-Testweg

Das Beispiel setzt eine React- und TypeScript-Anwendung mit Utility-Klassen voraus. Passen Sie die Befehle an den Paketmanager und das Framework des Zielprojekts an.

npm install class-variance-authority clsx tailwind-merge
npx storybook@latest init
npx storybook add @storybook/addon-a11y
npx storybook add @storybook/addon-vitest
npm install -D @playwright/test concurrently http-server wait-on
npx playwright install chromium

Das Vitest addon benötigt ein Vite-basiertes Storybook-Framework oder die unterstützte Next.js-Vite-Integration. Für solche Projekte lautet der empfohlene Testbefehl vitest --project=storybook. Kann ein bestehendes Projekt diese Integration nicht verwenden, ist der ältere @storybook/test-runner nur ein dokumentierter Fallback beziehungsweise ein Zwischenschritt gemäß dem offiziellen Migrationsleitfaden zum Vitest addon. Er sollte nicht als neue Standardkonfiguration eingeführt werden.

Die Skripte machen denselben Ablauf lokal und in CI reproduzierbar:

{
  "scripts": {
    "tokens:build": "node scripts/build-tokens.mjs",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build",
    "test:storybook": "vitest --project=storybook",
    "test:visual": "playwright test tests/button.visual.spec.ts"
  }
}

Design Tokens als verbindlichen Vertrag aufbauen

Teilen Sie die Tokens in drei Ebenen. Primitive Tokens speichern Rohwerte. Semantische Tokens beschreiben eine Bedeutung wie Oberfläche, Text oder Fokus. Komponenten-Tokens verbinden diese Bedeutung mit einem konkreten Zustand, etwa dem Hintergrund eines primären Buttons.

{
  "$schema": "https://www.designtokens.org/schemas/2025.10/format.json",
  "primitive": {
    "color": {
      "blue": {
        "50": {
          "$type": "color",
          "$value": { "colorSpace": "srgb", "components": [0.9373, 0.9647, 1], "hex": "#eff6ff" }
        },
        "600": {
          "$type": "color",
          "$value": { "colorSpace": "srgb", "components": [0.1451, 0.3882, 0.9216], "hex": "#2563eb" }
        },
        "700": {
          "$type": "color",
          "$value": { "colorSpace": "srgb", "components": [0.1137, 0.3059, 0.8471], "hex": "#1d4ed8" }
        }
      },
      "gray": {
        "50": {
          "$type": "color",
          "$value": { "colorSpace": "srgb", "components": [0.9765, 0.9804, 0.9843], "hex": "#f9fafb" }
        },
        "200": {
          "$type": "color",
          "$value": { "colorSpace": "srgb", "components": [0.898, 0.9059, 0.9216], "hex": "#e5e7eb" }
        },
        "900": {
          "$type": "color",
          "$value": { "colorSpace": "srgb", "components": [0.0667, 0.0941, 0.1529], "hex": "#111827" }
        }
      },
      "red": {
        "600": {
          "$type": "color",
          "$value": { "colorSpace": "srgb", "components": [0.8627, 0.149, 0.149], "hex": "#dc2626" }
        },
        "700": {
          "$type": "color",
          "$value": { "colorSpace": "srgb", "components": [0.7255, 0.1098, 0.1098], "hex": "#b91c1c" }
        }
      },
      "white": {
        "$type": "color",
        "$value": { "colorSpace": "srgb", "components": [1, 1, 1], "hex": "#ffffff" }
      }
    },
    "space": {
      "2": { "$type": "dimension", "$value": { "value": 0.5, "unit": "rem" } },
      "3": { "$type": "dimension", "$value": { "value": 0.75, "unit": "rem" } },
      "4": { "$type": "dimension", "$value": { "value": 1, "unit": "rem" } },
      "6": { "$type": "dimension", "$value": { "value": 1.5, "unit": "rem" } }
    },
    "radius": {
      "md": { "$type": "dimension", "$value": { "value": 0.375, "unit": "rem" } },
      "lg": { "$type": "dimension", "$value": { "value": 0.5, "unit": "rem" } }
    }
  },
  "semantic": {
    "color": {
      "surface": { "$type": "color", "$value": "{primitive.color.white}" },
      "text": { "$type": "color", "$value": "{primitive.color.gray.900}" },
      "border": { "$type": "color", "$value": "{primitive.color.gray.200}" },
      "focus": { "$type": "color", "$value": "{primitive.color.blue.600}" }
    }
  },
  "component": {
    "button": {
      "primary": {
        "background": { "$type": "color", "$value": "{primitive.color.blue.600}" },
        "backgroundHover": { "$type": "color", "$value": "{primitive.color.blue.700}" },
        "text": { "$type": "color", "$value": "{primitive.color.white}" }
      },
      "danger": {
        "background": { "$type": "color", "$value": "{primitive.color.red.600}" },
        "backgroundHover": { "$type": "color", "$value": "{primitive.color.red.700}" },
        "text": { "$type": "color", "$value": "{primitive.color.white}" }
      }
    }
  }
}

Aus dieser Datei erzeugt das folgende Skript CSS Custom Properties und eine typisierte Token-Map für TypeScript:

import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname } from "node:path";

const source = JSON.parse(readFileSync("tokens.json", "utf8"));

function getToken(path) {
  const node = path.split(".").reduce((current, key) => current?.[key], source);
  if (!node || typeof node.$value === "undefined") {
    throw new Error(`Unknown token reference: ${path}`);
  }
  return node.$value;
}

function resolveValue(value, stack = []) {
  if (typeof value === "string" && value.startsWith("{") && value.endsWith("}")) {
    const path = value.slice(1, -1);
    if (stack.includes(path)) {
      throw new Error(`Circular token reference: ${[...stack, path].join(" -> ")}`);
    }
    return resolveValue(getToken(path), [...stack, path]);
  }
  return value;
}

function toCssValue(value) {
  if (value && typeof value === "object") {
    if (typeof value.hex === "string") return value.hex;
    if (typeof value.value === "number" && typeof value.unit === "string") {
      return `${value.value}${value.unit}`;
    }
    throw new Error(`Unsupported token value: ${JSON.stringify(value)}`);
  }
  return String(value);
}

function walk(node, pathParts = [], result = {}) {
  if (!node || typeof node !== "object") return result;

  if (node && typeof node === "object" && typeof node.$value !== "undefined") {
    result[pathParts.join("-")] = toCssValue(resolveValue(node.$value));
    return result;
  }

  for (const [key, value] of Object.entries(node)) {
    if (key.startsWith("$")) continue;
    walk(value, [...pathParts, key], result);
  }

  return result;
}

const flat = walk(source);
const css = [
  ":root {",
  ...Object.entries(flat).map(([name, value]) => `  --${name}: ${value};`),
  "}",
  ""
].join("\n");

mkdirSync(dirname("src/styles/tokens.css"), { recursive: true });
mkdirSync(dirname("src/tokens.ts"), { recursive: true });
writeFileSync("src/styles/tokens.css", css);
writeFileSync("src/tokens.ts", `export const tokens = ${JSON.stringify(flat, null, 2)} as const;\n`);

console.log(`Generated ${Object.keys(flat).length} tokens.`);

Lassen Sie Claude Code zunächst nur Kandidaten erfassen. Ein guter erster Auftrag lautet: „Finde wiederholte rohe Farb- und Abstandswerte, ordne sie vorgeschlagenen Tokens zu und liefere vor jeder Änderung einen Bericht.“ So kann das Team Namen und Bedeutungen prüfen, bevor viele Dateien betroffen sind.

Typisierte React-Komponenten bauen

Die Komponentenebene sollte vorhersehbar sein. Der folgende Button enthält Varianten, Größen, Lade- und Deaktivierungszustand sowie einen sichtbaren Fokus. Die öffentliche API bleibt klein, während wiederkehrende Klassen an einer Stelle gepflegt werden.

import { forwardRef, type ButtonHTMLAttributes } from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

const buttonVariants = cva(
  [
    "inline-flex items-center justify-center gap-2 rounded-md font-medium",
    "transition-colors focus-visible:outline-none focus-visible:ring-2",
    "focus-visible:ring-[var(--semantic-color-focus)] focus-visible:ring-offset-2",
    "disabled:pointer-events-none disabled:opacity-50"
  ],
  {
    variants: {
      variant: {
        primary: [
          "bg-[var(--component-button-primary-background)]",
          "text-[var(--component-button-primary-text)]",
          "hover:bg-[var(--component-button-primary-backgroundHover)]"
        ],
        secondary: "border border-[var(--semantic-color-border)] bg-[var(--semantic-color-surface)] text-[var(--semantic-color-text)] hover:bg-gray-50",
        danger: [
          "bg-[var(--component-button-danger-background)]",
          "text-[var(--component-button-danger-text)]",
          "hover:bg-[var(--component-button-danger-backgroundHover)]"
        ]
      },
      size: {
        sm: "h-8 px-3 text-sm",
        md: "h-10 px-4 text-sm",
        lg: "h-12 px-6 text-base"
      }
    },
    defaultVariants: {
      variant: "primary",
      size: "md"
    }
  }
);

export interface ButtonProps
  extends ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  loading?: boolean;
}

export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
  { className, variant, size, loading = false, disabled, children, ...props },
  ref
) {
  return (
    <button
      ref={ref}
      className={cn(buttonVariants({ variant, size }), className)}
      disabled={disabled || loading}
      aria-busy={loading || undefined}
      {...props}
    >
      {loading ? (
        <span
          aria-hidden="true"
          className="h-4 w-4 animate-spin rounded-full border-2 border-current border-r-transparent"
        />
      ) : null}
      <span>{children}</span>
    </button>
  );
});

Die entscheidende Review-Frage lautet nicht „Sieht der Button schön aus?“, sondern „Ist diese API stabil genug, damit viele Produktteams sie verwenden können?“. Menschen prüfen insbesondere Benennung, Default-Verhalten und mögliche Abwärtskompatibilität.

Storybook als ausführbare Spezifikation nutzen

Jeder fachlich relevante Zustand sollte als Story existieren. Fehlt ein Zustand in Storybook, lässt er sich nur schwer gemeinsam besprechen, visuell vergleichen oder automatisiert testen.

import type { Meta, StoryObj } from "@storybook/react-vite";
import { Button } from "./Button";

const meta = {
  title: "Design System/Button",
  component: Button,
  parameters: {
    layout: "centered",
    a11y: {
      test: "error"
    }
  },
  argTypes: {
    variant: {
      control: "select",
      options: ["primary", "secondary", "danger"]
    },
    size: {
      control: "select",
      options: ["sm", "md", "lg"]
    },
    loading: { control: "boolean" },
    disabled: { control: "boolean" }
  }
} satisfies Meta<typeof Button>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Primary: Story = {
  args: {
    children: "Save changes",
    variant: "primary"
  }
};

export const Danger: Story = {
  args: {
    children: "Delete",
    variant: "danger"
  }
};

export const Loading: Story = {
  args: {
    children: "Saving",
    loading: true
  }
};

export const AllStates: Story = {
  render: () => (
    <div className="flex flex-wrap items-center gap-3">
      <Button variant="primary" size="sm">Small</Button>
      <Button variant="primary" size="md">Medium</Button>
      <Button variant="primary" size="lg">Large</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="danger">Danger</Button>
      <Button disabled>Disabled</Button>
      <Button loading>Loading</Button>
    </div>
  )
};

Bitten Sie Claude Code, bestehende Stories beizubehalten, fehlende Zustände zu ergänzen und jede Änderung einer Story-ID zu erklären. Dadurch bleiben bestehende visuelle Snapshots und a11y-Berichte zuordenbar.

Komponenten-, a11y- und visuelle Prüfungen in CI ausführen

Automatisierte Accessibility-Prüfungen ersetzen keine Tastatur- und Screenreader-Prüfung. Sie entdecken jedoch viele strukturelle Verstöße früh. Für Vite-basiertes Storybook ist @storybook/addon-vitest der aktuelle Standard: Es wandelt Stories in Browser-Tests um. Meldet das Accessibility addon bei parameters.a11y.test = "error" einen Verstoß, schlägt der Komponententest fehl.

Führen Sie in CI npm run test:storybook -- --run aus. Anders als beim älteren test-runner muss für die Komponenten- und a11y-Tests kein separater Storybook-Server laufen. Ein gebauter Storybook-Server bleibt im folgenden Beispiel nur für den eigenen Playwright-Screenshot nötig.

Beginnen Sie mit wenigen, wertvollen visuellen Tests. Dynamische Daten, Animationen oder externe Schriften können unnötig instabile Snapshots erzeugen.

Führen Sie vor dem Aktivieren der CI im Zielprojekt einmal npx playwright test tests/button.visual.spec.ts --update-snapshots aus, prüfen Sie das Referenzbild und committen Sie es. Ohne Referenzbild schlägt der erste Vergleich fehl, weil Playwright keine Vergleichsbasis hat.

import { expect, test } from "@playwright/test";

test("button all states visual snapshot", async ({ page }) => {
  await page.goto("http://127.0.0.1:6006/iframe.html?id=design-system-button--all-states");
  await expect(page).toHaveScreenshot("button-all-states.png", {
    fullPage: true,
    animations: "disabled"
  });
});

Danach wird derselbe Ablauf in GitHub Actions ausgeführt:

name: design-system-quality

on:
  pull_request:
    paths:
      - "tokens.json"
      - "scripts/build-tokens.mjs"
      - "src/components/**"
      - "src/styles/**"
      - ".storybook/**"
      - "tests/**"
      - "package.json"
      - "package-lock.json"

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm
      - run: npm ci
      - run: npm run tokens:build
      - run: npx playwright install --with-deps chromium
      - run: npm run test:storybook -- --run
      - run: npm run build-storybook
      - run: >
          npx concurrently -k -s first -n server,tests
          "npx http-server storybook-static -p 6006"
          "npx wait-on http://127.0.0.1:6006 && npm run test:visual"

Wenn CI fehlschlägt, geben Sie Claude Code die betroffene Story-ID, den konkreten axe-Verstoß, die geänderten Dateien und den visuellen Diff. Vollständige Logs können Geheimnisse oder private Pfade enthalten und sollten nicht ungeprüft in einen Prompt kopiert werden.

Eine realistische Grenze für die Figma-Integration

Figma Variables sind eine wertvolle Eingabe für Token-Arbeit. Eine automatische Synchronisation in beide Richtungen ist am Anfang dennoch riskant: Unfreigegebene Experimente, alte Komponentennamen oder private Designnotizen können unbeabsichtigt in Produktions-Tokens gelangen.

BereichSinnvolle AutomatisierungVermeiden
Figma VariablesExportieren und mit tokens.json vergleichenProduktions-Tokens blind überschreiben
Figma-KomponentenZustände und Prop-Kandidaten sammelnReact-APIs automatisch festlegen
Figma-KommentareOffene Fragen zusammenfassenEndgültige Designabsicht erraten
Storybook-LinksStory-URLs an ein Design-Review anhängenStorybook als Designfreigabe behandeln

Lassen Sie Claude Code zuerst einen Prüfbericht erstellen, ohne die Token-Datei zu verändern:

Lies figma-tokens-export.json und tokens.json.
Erstelle einen Markdown-Bericht mit:
1. Tokens, die in Figma, aber nicht im Code existieren
2. Tokens, die im Code, aber nicht in Figma existieren
3. Wertunterschiede bei übereinstimmenden semantischen Tokens
Bearbeite tokens.json nicht. Benenne keine Tokens um. Markiere riskante Unterschiede bei Fokus-, Gefahren- und Textfarben.

Das Ziel ist nicht Synchronisation um ihrer selbst willen. Das Ziel ist ein kleiner, nachvollziehbarer Diff, über den Design und Entwicklung gemeinsam entscheiden können.

Use case 1: Zustände in einer SaaS-Verwaltung vereinheitlichen

In einer SaaS-Verwaltung tauchen Buttons, Formulare, Tabellen und Dialoge in vielen Zuständen auf. Ein Team kann Claude Code zunächst alle aktuellen Button-Verwendungen erfassen lassen. Danach werden Kompatibilitäts-Props definiert und nur ein Bildschirm migriert.

Der Mensch entscheidet, welche Zustände fachlich verschieden sind. Claude Code ergänzt die Implementierung, Stories und Tests. Erst wenn der visuelle Diff und die Tastaturbedienung dieses einen Bildschirms akzeptiert sind, folgt der nächste Bereich. So bleibt ein Rollback klein.

Use case 2: Marken in einem White-Label-Produkt wechseln

Bei White-Label-Produkten ändern sich primitive Markenfarben je Kunde, während semantische Tokens wie surface, text oder danger stabil bleiben. Claude Code kann aus einer geprüften Markendatei CSS Custom Properties und Umschalter für Storybook-Themes erzeugen.

Nicht automatisiert werden sollte die Bedeutung einer Farbe. Der Mensch prüft Kontrast, Markenwirkung und rechtliche Vorgaben. CI verifiziert anschließend, dass jede Marke dieselben Komponenten und Zustände bauen kann.

Use case 3: Legacy-CSS schrittweise bereinigen

In gewachsenem CSS finden sich häufig zehn ähnliche Blautöne und leicht abweichende Abstände. Claude Code kann Rohwerte zählen, nach Verwendung gruppieren und eine Migrationstabelle mit Token-Kandidaten erstellen. Der erste Schritt ist ausdrücklich ein Bericht, keine Massenersetzung.

Nach der Freigabe wird eine Komponente nach der anderen umgestellt. Visuelle Snapshots zeigen, ob ein vermeintlich gleicher Wert doch eine besondere Bedeutung hatte. Das verhindert, dass eine Aufräumaktion unbemerkt das Produktdesign verändert.

Use case 4: Marketing- und Anfragepfade messbar halten

CTA-Buttons, Preiskarten und Formularzustände müssen auf Landingpages konsistent sein. Ein Designsystem erleichtert A/B-Tests, weil eine Variante an einer kontrollierten Stelle verändert wird. Claude Code kann betroffene Stories und Screenshots ergänzen und prüfen, ob Lade-, Fehler- und Erfolgszustände vorhanden sind.

Welche Variante geschäftlich sinnvoll ist, entscheidet weiterhin ein Mensch anhand echter Messdaten. Das Designsystem stellt nur sicher, dass der Versuch technisch vergleichbar und barrierearm umgesetzt wird.

Typische Fallstricke mit Ursache und Korrektur

Primitive Tokens direkt in Komponenten

Ursache: Ein Entwickler verwendet blue-600, weil der Wert sofort verfügbar ist. Folge: Eine Markenänderung verlangt Suchen und Ersetzen in vielen Komponenten. Korrektur: Komponenten greifen auf semantische oder komponentenspezifische Tokens zu; primitive Werte bleiben in der untersten Ebene.

Storybook läuft nur lokal

Ursache: Stories werden als Dokumentation betrachtet, nicht als Testeingabe. Folge: Der Katalog kann unbemerkt brechen. Korrektur: Story-Komponententests mit @storybook/addon-vitest und vitest --project=storybook in jedem betroffenen Pull Request ausführen.

Visuelle Tests werden zu früh auf alles ausgedehnt

Ursache: Das Team möchte sofort vollständige Abdeckung. Folge: Animationen, Datumswerte, externe Fonts und zufällige IDs erzeugen laute Diffs. Korrektur: Dynamische Inhalte einfrieren und mit wenigen geschäftskritischen Stories beginnen.

Ein bestandener axe-Test gilt als vollständige Freigabe

Ursache: Ein grüner automatischer Check wirkt objektiv. Folge: Kontext, Textqualität, sinnvolle Fokusreihenfolge und Screenreader-Verständlichkeit bleiben ungeprüft. Korrektur: Automatisierte Tests mit Tastatur- und Screenreader-Prüfungen durch Menschen ergänzen.

Claude Code soll die gesamte Migration auf einmal erledigen

Ursache: Ein großer Prompt verspricht schnelle Fertigstellung. Folge: API-Änderungen, visuelle Abweichungen und Regressionen vermischen sich in einem kaum prüfbaren Diff. Korrektur: Pro Auftrag eine Komponente, feste Dateigrenzen und verpflichtende Tests verwenden.

Checkliste vor dem Merge

  • Token-Namen drücken Bedeutung aus und nicht nur ein Aussehen.
  • Komponenten-Props sind klein, typisiert und stabil.
  • Disabled-, Loading-, Error-, Fokus- und Hover-Zustände existieren in Storybook.
  • Die ausschließliche Bedienung per Tastatur wurde geprüft.
  • ARIA wird nur dort ergänzt, wo natives HTML nicht ausreicht.
  • Ein Mensch hat Änderungen visueller Snapshots geprüft.
  • Figma-Unterschiede sind als Review-Artefakt gespeichert.
  • Claude Code hat ausschließlich die erlaubten Dateibereiche geändert.
  • Prompts, Logs, Stories und Screenshots enthalten keine Geheimnisse oder privaten Kundendaten.

Speichern Sie diese Liste in den Projektanweisungen. Dann kann Claude Code sie auch in späteren Sitzungen als Abnahmekriterium verwenden.

Der nächste sinnvolle Schritt

Prüfen Sie zuerst, ob tokens.json CSS-Variablen und TypeScript-Konstanten erzeugt, ob die Button-Stories alle Zustände rendern und ob CI den Storybook-Build, Accessibility-Prüfungen und visuelle Snapshots reproduziert. Halten Sie die Figma-Integration im reinen Berichtsmodus, bis das Team die Quelle der Wahrheit festgelegt hat.

Wenn Ihr Team Unterstützung bei Designsystem-Implementierung, Storybook-Einführung, Accessibility-Review oder einem Claude-Code-Ablauf für UI-Refactoring benötigt, finden Sie den passenden Einstieg auf der Seite für Schulung und Beratung.

Was tatsächlich getestet wurde

Am 22. Juli 2026 wurde der in diesem Artikel gezeigte Code aus build-tokens.mjs extrahiert und mit dem vollständigen tokens.json-Beispiel ausgeführt. Der Prozess endete mit Exit-Code 0, erzeugte 25 CSS Custom Properties sowie die TypeScript-Token-Map und löste die Referenz {primitive.color.blue.600} zu #2563eb auf. Ein negativer Testfall mit einer unbekannten Referenz endete mit einem von null verschiedenen Exit-Code und der Meldung Unknown token reference.

Zusätzlich wurden die JSON-Ausschnitte geparst sowie Code-Fences und interne Links geprüft. Die Storybook-Befehle wurden mit der aktuellen offiziellen Dokumentation zum Vitest addon und zur Migration abgeglichen. Storybook selbst ist in diesem Website-Repository nicht installiert; Komponenten- und visuelle Tests müssen deshalb vor der Übernahme im jeweiligen Zielprojekt ausgeführt werden.

#Claude Code #Designsystem #Design Tokens #Storybook #Barrierefreiheit
Kostenlos

Kostenloses PDF: Claude-Code-Cheatsheet

E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.

Wir schützen Ihre Daten und senden keinen Spam.

Masa

Über den Autor

Masa

Engineer für praktische Claude-Code-Workflows und Team-Einführung.