Komponenten-Overkill: Wann Copy/Paste besser ist als die 100. Abstraktion

Wann Copy/Paste besser ist als die 100. Abstraktion

Du willst sauberen Code. Aber wenn jede Kleinigkeit zur “shared component” wird, baust du dir ein Wartungs-Abo. Manchmal ist Copy/Paste einfach die erwachsenere Entscheidung.

Es gibt zwei Arten von Teams:

  • Team A kopiert Code und hat manchmal Doppelstellen.
  • Team B abstrahiert alles weg und hat am Ende Props-Hölle, kaputte Edge-Cases und eine Component Library, die keiner anfassen will.

Die Pointe: Beides kann richtig sein – je nach Kontext. Der Fehler ist nicht “Copy/Paste” oder “Abstraktion”. Der Fehler ist falsches Timing und falscher Scope.

Dieser Artikel ist die Entscheidungshilfe: Wann du kopierst, wann du extrahierst, und wann du nur ein Pattern brauchst.

Warum Abstraktionen im UI so oft schaden

1) UI ist voller Ausnahmen (und Ausnahmen killen generische APIs)

Backend-Logik lässt sich oft sauber generalisieren. UI nicht immer. Heute ist es “nur ein Button”, morgen braucht ein Screen ein Icon links, der nächste einen Spinner, der dritte eine Sonderfarbe, der vierte einen Tooltip. Und zack: Button v27.

2) Abstraktion erzeugt Coupling

Wenn 20 Screens eine Shared Component nutzen, dann ist jede Änderung plötzlich ein Mini-Migrationsprojekt. Copy/Paste hat das Problem nicht: du änderst genau da, wo’s nötig ist.

3) “Leaky Abstraction” im Frontend ist real

Wenn deine Komponente intern zu viel “magisch” macht, musst du am Ende doch wieder ins Innere greifen: Hacks, Overrides, Sonderprops. Das ist das Gegenteil von “sauber”.

Wann Copy/Paste wirklich die bessere Wahl ist

Copy/Paste ist gut, wenn…

  • das Feature noch wackelt (Produkt ändert sich, UX ist im Fluss).
  • du erst 1–2 Vorkommen hast (noch kein Pattern, nur Zufall).
  • die Unterschiede groß sind (Optik/Verhalten wirklich unterschiedlich).
  • die Kopie lokal bleiben soll (ein Screen braucht etwas Spezielles, das nie wiederkommt).

Copy/Paste ist gefährlich, wenn…

  • du Sicherheits-/Compliance-Logik kopierst (Auth, Sanitizing, Security-Relevantes) – das gehört zentral, keine Diskussion.
  • du Bugs an 5 Stellen fixen musst, weil du keine gemeinsame Stelle hast.
  • du denselben Code in 10 Dateien mit minimalen Abweichungen hast (das ist ein Pattern, kein Zufall mehr).

Wann Abstraktion sich lohnt (und wie du sie klein hältst)

Rule of Three: ab dem dritten Mal wird’s interessant

Die “Rule of Three” ist eine bekannte Refactoring-Heuristik: Beim ersten Mal baust du es, beim zweiten Mal kopierst du es (weil du noch nicht sicher bist), beim dritten Mal extrahierst du. Das ist keine Naturgesetz-Nummer, aber eine sehr gute Bremse gegen “zu früh abstrahieren”.

Die 3 Fragen vor jeder Shared Component

  1. Ist das Verhalten stabil? Oder ändert sich das jede Woche?
  2. Ist es wirklich dasselbe Problem? Oder nur “sieht ähnlich aus”?
  3. Kann ich es als Pattern lösen? (Tokens, Layout-Utility, Composition) statt als “God Component”?

Vergleichstabelle: Copy/Paste vs Shared Component vs Pattern/Tokens

Ansatz Wann richtig Vorteil Risiko Praxis-Regel
Copy/Paste frühe Phase, wenige Vorkommen, viel Veränderung lokal, schnell, keine Coupling-Falle Bugfix mehrfach, Drift möglich Nur UI/Presentation kopieren, nicht Sicherheitslogik
Shared Component stabiles Verhalten, echtes Wiederholungspattern ein Fix = überall fix Props-Hölle, Coupling, Breaking Changes API klein halten, “Escape Hatches” minimieren
Pattern / Tokens du willst Konsistenz, nicht zwingend Wiederverwendung wenig Overhead, hohe Wirkung zu vage Regeln werden ignoriert Tokens sind verbindlich, Patterns kurz dokumentieren

So setzt du’s um

5-Schritte-Plan: von Copy/Paste zu sauberer Abstraktion (ohne Overkill)

  1. Dupliziere bewusst: Kopiere erstmal, aber markiere es mental als “kann ein Pattern werden”.
  2. Beobachte Unterschiede: Welche Teile sind wirklich gleich, welche sind “Sonderlocken”?
  3. Extrahiere das Stabile: erst Tokens/Utilities (Spacing/Typo), dann kleine Bausteine, zuletzt erst “große” Komponenten.
  4. Halte die API klein: lieber 2 Komponenten als 1 Universal-Teil mit 20 Props.
  5. Dokumentiere 10 Zeilen: “Wofür ist das? Wofür nicht?” – das spart dir mehr als jede fancy Story.

Mini-Use-Case: “Card” ohne Universal-Monster

Du hast drei Screens mit Cards. Zwei sehen ähnlich aus, einer ist komplett anders. Statt “UniversalCard” machst du:

  • Tokens für Spacing, Radius, Shadow (Konsistenz)
  • CardShell als dünner Wrapper (nur Layout/Frame)
  • Content bleibt pro Screen lokal (Copy/Paste, weil’s wirklich anders ist)
// Denkmodell (framework-agnostisch):
// CardShell: Rahmen + Spacing + States
// CardContent: bleibt lokal, weil Produktanforderungen variieren
// Ergebnis: Konsistenz ohne Props-Hölle

Typische Fehler & wie du sie vermeidest

  • Fehler: “Wir müssen DRY sein, sofort.” Fix: Erst beobachten, dann extrahieren (Rule of Three).
  • Fehler: Zu generische API. Fix: Bau für konkrete Use-Cases, nicht für Fantasie-Zukunft.
  • Fehler: Escape Hatches überall (className passt schon). Fix: Wenn du ständig “ausbrechen” musst, ist die Abstraktion falsch geschnitten.
  • Fehler: Breaking Changes ohne Plan. Fix: Versionieren oder Migrationspfad (oder: nicht sharen, wenn’s volatil ist).
  • Fehler: Konsistenz wird über Komponenten erzwungen. Fix: Konsistenz primär über Tokens/Guidelines sichern.

Fazit: Abstraktion ist ein Investment – Copy/Paste ist manchmal Cash

Wenn du nicht sicher bist: kopier zuerst. Lass das Muster sichtbar werden. Dann refactorst du in etwas Kleines, Stabiles. Und wenn du doch eine Shared Component baust: halte sie so klein, dass sie nicht zum Produktteam in deinem Produkt wird.

Nächster Schritt: Such dir 1 Bereich mit offensichtlichem Komponenten-Overkill (z.B. Buttons/Cards) und zieh den Scope runter: Tokens + 1 Shell + lokale Inhalte. Das ist meistens schon 80% Gewinn.

FAQ

Wenn das Verhalten noch nicht stabil ist, du erst 1–2 Vorkommen hast oder die Unterschiede groß sind. Copy/Paste hält Änderungen lokal und verhindert Coupling, solange du es bewusst nutzt.

Wenn eine Komponente immer mehr Props bekommt “für alle Fälle”, du ständig Overrides brauchst oder die Doku länger ist als der eigentliche Nutzen. Das sind starke Signale für falschen Schnitt.

DRY ist super, wenn du wirklich dasselbe Problem mehrfach hast und das Verhalten stabil ist. Im UI ist WET (“Write Everything Twice” als Gegenpol) manchmal gesünder, bis das Pattern klar ist. Danach refactorst du gezielt.

Heuristik: 1x bauen, 2x kopieren, beim 3. Mal extrahieren. Nicht als Dogma, aber als Bremse gegen “zu frühe Abstraktion”.

Wenn du mehrere Teams/Projekte hast, Wiederverwendung real ist und du Ownership/Governance stemmen kannst. Ohne Ownership wird eine Library schnell zur Altlast.

Extrahiere zuerst das Stabile (Tokens, kleine Utilities, Shells). Halte die API klein. Und dokumentiere kurz “wofür” und “wofür nicht”. Wenn du ständig Sonderfälle adden musst, ist der Schnitt falsch.

Über Tokens (Spacing/Typo/Colors), ein paar Kernkomponenten und klare Patterns. Konsistenz ist oft ein Design-Token-Problem, kein “noch eine Komponente”-Problem.