shadcn/ui Installation und Theme-Anpassung: Der vollständige Leitfaden (inkl. CSS-Variablen)
Beim ersten Kontakt mit shadcn/ui war ich von der Idee verwirrt, dass es „kein npm-Paket” ist. Code ins Projekt kopieren? Das klang ziemlich altmodisch.
Nach ein paar Projekten wurde klar: Genau das ist der Vorteil – Sie besitzen den gesamten Komponentenquellcode, können alles anpassen, ohne Versionskonflikte oder Designvorgaben einer Bibliothek.
Heute geht es um Installation, Konfiguration und Theme-Anpassung von shadcn/ui – mit Fokus auf markenspezifische Design-Systeme über CSS-Variablen. Nach diesem Artikel sollten Sie die Grundkonfiguration in etwa 5 Minuten schaffen und danach das Theme nach Ihren Wünschen feinjustieren.
1. Schnelle Installation: Zwei Wege
Weg 1: CLI-Initialisierung (empfohlen)
Für neue Projekte direkt diesen Befehl:
npx shadcn@latest init
Die CLI stellt Fragen: TypeScript oder JavaScript? Welcher Stil? Welches Standard-Theme? Interaktiv – einfach den Hinweisen folgen.
Danach kommen typischerweise diese Dateien dazu:
components.json– Konfigurationsdateilib/utils.ts– Hilfsfunktionencomponents/ui/– Verzeichnis für Komponenten
Komponenten hinzufügen ist ebenso einfach, z. B. ein Button:
npx shadcn@latest add button
Der Code landet in components/ui/button.tsx – direkt importieren und nutzen.
Achtung: Wenn das Projekt schon weiter fortgeschritten ist, enthält tailwind.config.js und globals.css oft viel Eigenes. Der init-Befehl überschreibt diese Dateien – am besten ganz am Anfang installieren.
Ein Blogger formulierte es treffend: shadcn/ui als eine der „ersten Abhängigkeiten” behandeln, nicht erst später nachrüsten. Lehren aus der Praxis.
Weg 2: Manuelle Installation (für bestehende Projekte)
Ist das Projekt schon ausgereift, ist das Überschreiben durch die CLI riskant – dann manuell vorgehen.
Schritt 1: Tailwind CSS installieren
shadcn-Komponenten basieren auf Tailwind. Fehlt Tailwind, zuerst installieren – die offizielle Anleitung ist klar.
Schritt 2: Abhängigkeiten installieren
npm install class-variance-authority clsx tailwind-merge
npm install lucide-react
class-variance-authority (CVA) ist praktisch – später für Komponenten-Varianten.
Schritt 3: Pfad-Aliase konfigurieren
In tsconfig.json ergänzen:
{
"compilerOptions": {
"paths": {
"@/*": ["./*"]
}
}
}
So importieren Sie mit @/components/ui/button statt langer relativer Pfade.
Schritt 4: components.json erstellen
Im Projektroot anlegen:
{
"style": "new-york",
"rsc": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "app/globals.css",
"baseColor": "neutral",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
}
}
cssVariables: true ist entscheidend – Theme über CSS-Variablen statt Tailwind-Utility-Klassen.
Schritt 5: Basis-Styles hinzufügen
In globals.css die shadcn-Basis-Styles einfügen – Details folgen im Theme-Abschnitt.
2. Theme-System verstehen: CSS-Variablen
Das shadcn/ui-Theme basiert auf einer einfachen Konvention: Jede Farbe hat background- und foreground-Variablen.
Beispiel:
:root {
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
}
--primary ist die Hintergrundfarbe des Buttons, --primary-foreground die Textfarbe darauf. Eine Variable ändern – alle zugehörigen Komponenten passen sich an.
CSS-Variablen-Liste
shadcn/ui definiert standardmäßig:
| Variable | Verwendung |
|---|---|
--background | Seitenhintergrund |
--foreground | Seitentext |
--card | Kartenhintergrund |
--card-foreground | Kartentext |
--popover | Popover-Hintergrund |
--popover-foreground | Popover-Text |
--primary | Primärfarbe (Buttons, Links) |
--primary-foreground | Text auf Primärfarbe |
--secondary | Sekundärfarbe |
--secondary-foreground | Text auf Sekundärfarbe |
--muted | Gedämpfter Hintergrund |
--muted-foreground | Gedämpfter Text |
--accent | Akzentfarbe |
--accent-foreground | Text auf Akzentfarbe |
--destructive | Gefährliche Aktion (Löschen-Button) |
--destructive-foreground | Text auf Destructive |
--border | Rahmen |
--input | Eingabefeld |
--ring | Fokusring |
Viele Namen – aber das background/foreground-Muster macht es leicht merkbar.
Das Geheimnis des HSL-Formats
Die Farbwerte sind nicht im Standard-HSL-Format:
/* ❌ Standard-HSL */
--primary: hsl(222.2, 47.4%, 11.2%);
/* ✅ shadcn-Format */
--primary: 222.2 47.4% 11.2%;
Warum das „nackte” Format?
Tailwind unterstützt Transparenz-Modifikatoren wie bg-primary/50 für 50 % Deckkraft. Bei vollem hsl()-Wert in der Variable funktioniert das nicht.
Im nackten Format ergänzt Tailwind automatisch hsl() und Transparenz – elegante Lösung.
3. Marken-Theme anpassen
Methode 1: CSS-Variablen direkt ändern
Am einfachsten: globals.css öffnen, :root-Abschnitt, Farbwerte anpassen.
Primärfarbe von Standard-Blau auf Lila:
:root {
--primary: 270 60% 60%;
--primary-foreground: 0 0% 100%;
}
.dark {
--primary: 270 60% 70%;
--primary-foreground: 0 0% 0%;
}
Speichern – alle Buttons und Links mit bg-primary werden lila.
Methode 2: OKLCH-Farbraum (Tailwind v4)
Mit Tailwind v4 lohnt sich OKLCH: farblich näher an menschlicher Wahrnehmung als HSL, gleichmäßigere Abstufungen.
:root {
--primary: oklch(0.6 0.2 270);
--primary-foreground: oklch(0.98 0 0);
}
oklch(0.6 0.2 270) bedeutet:
0.6– Helligkeit (0–1)0.2– Sättigung (ca. 0–0,4)270– Farbton in Grad (0–360)
Methode 3: Online-Tools
Farben selbst zusammenstellen zu mühsam? Online-Generatoren nutzen.
Empfehlung: Shadcn Theme Generator
Primärfarbe wählen – das Tool erzeugt das komplette CSS-Variablen-Set für Hell- und Dark-Mode. In globals.css einfügen.
4. Dark-Mode-Konfiguration
Theme-Umschaltung mit next-themes
shadcn/ui bringt keine Theme-Umschaltung mit – next-themes übernimmt das.
Installation:
npm install next-themes
In layout.tsx konfigurieren:
import { ThemeProvider } from "next-themes"
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="de" suppressHydrationWarning>
<body>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
>
{children}
</ThemeProvider>
</body>
</html>
)
}
Wichtige Punkte:
suppressHydrationWarningist Pflicht – sonst Hydration-Warnungenattribute="class"– Theme per CSS-Klasse umschaltendefaultTheme="system"– Standard folgt dem SystemenableSystem– System-Theme-Erkennung aktivieren
Theme-Umschalt-Button
Mit dem useTheme-Hook aktuelles Theme und Umschaltfunktion:
import { useTheme } from "next-themes"
import { Moon, Sun } from "lucide-react"
export function ThemeToggle() {
const { theme, setTheme } = useTheme()
return (
<button
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
className="p-2 rounded-md hover:bg-accent"
>
{theme === "dark" ? <Sun size={20} /> : <Moon size={20} />}
</button>
)
}
Standardmäßig Dark Mode
Website standardmäßig im Dark Mode – zwei Varianten:
Variante 1: dark-Klasse fest codieren
<html lang="de" className="dark">
Fest auf Dark – keine Umschaltung möglich.
Variante 2: Standard-Theme setzen
<ThemeProvider
attribute="class"
defaultTheme="dark" // Standard Dark
enableSystem={false} // System-Erkennung aus
>
Nutzer können umschalten, Startzustand ist Dark.
5. Erweiterte Anpassung: Komponenten-Varianten
Eigene Varianten mit CVA
Für Button-Stile wie „danger”, „success” oder Verläufe eignet sich CVA:
import { cva, type VariantProps } from "class-variance-authority"
const buttonVariants = cva(
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-9 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}
In der Komponente:
<button className={buttonVariants({ variant: "destructive", size: "lg" })}>
Löschen
</button>
shadcn-Quellcode nicht direkt ändern
Best Practice: Obwohl der Code in Ihrem Projekt liegt, Originaldateien nicht direkt bearbeiten – stattdessen Wrapper-Komponenten.
Grund: shadcn aktualisiert Komponenten regelmäßig. Geänderte Originaldateien erfordern manuelles Mergen.
Besserer Ansatz:
// components/brand-button.tsx
import { Button } from "@/components/ui/button"
import { cva } from "class-variance-authority"
const brandButtonVariants = cva("...", {
variants: {
brand: {
primary: "bg-brand-primary text-white",
secondary: "bg-brand-secondary text-black",
},
},
})
export function BrandButton({ brand, ...props }) {
return <Button className={brandButtonVariants({ brand })} {...props} />
}
Die Original-Button-Komponente bleibt unverändert – Ihre BrandButton-Anpassungen überleben shadcn-Updates.
6. Häufige Probleme und Fallstricke
Problem 1: Styles wirken nach Installation nicht
Prüfen:
- Wird
globals.cssinlayout.tsximportiert? - Enthält Tailwind
contentden Pfadcomponents/**/*? - Stimmen die Pfade in
components.json?
Problem 2: Flackern beim Theme-Wechsel
Meist Hydration-Mismatch. Sicherstellen:
<html>hatsuppressHydrationWarning- ThemeProvider umschließt die gesamte App
- theme nicht beim Server-Rendering auslesen (wäre undefined)
Problem 3: CSS-Variablen greifen nicht
Mögliche Ursachen:
- Falscher Variablenname (
--primary-foreground, nicht--primaryForeground) - Fehlende
.dark-Styles - Falsches Werteformat (nacktes HSL oder OKLCH)
Problem 4: Stilkonflikte mit bestehendem System
Bestehendes Stylesystem und shadcn können kollidieren. Lösungen:
- Namespace für shadcn-Komponenten (z. B.
shadcn-button) - Tailwind-Layer-Priorität anpassen
- Eigene Varianten mit CVA statt Default-Styles
7. Zusammenfassung
Installation und Konfiguration von shadcn/ui sind unkompliziert – entscheidend ist das Konzept „Code kopieren statt Paket-Abhängigkeit”. Vorteil: volle Kontrolle. Nachteil: Komponenten pro Projekt selbst pflegen.
Beim Theme ist das CSS-Variablen-System elegant: wenige Werte ändern, gesamte App-Farben passen sich an. Mit next-themes ist Hell/Dunkel-Umschaltung in wenigen Zeilen erledigt.
Empfehlungen:
- Neue Projekte per CLI initialisieren – weniger manuelle Konfiguration
- Semantische Farbvariablen wie primary, secondary statt konkreter Farbnamen
- Kontrast in Hell- und Dark-Mode testen – Lesbarkeit sicherstellen
- Wrapper-Komponenten statt Quellcode ändern – Updates bleiben einfach
Wenn Sie schnell ein UI mit Theme brauchen: shadcn/ui ausprobieren. Wer einmal Copy-and-Paste-Komponenten erlebt hat, versteht den Reiz.
Referenzen
- shadcn/ui Offizielle Dokumentation – Installation
- shadcn/ui Offizielle Dokumentation – Theming
- shadcn/ui Offizielle Dokumentation – Dark Mode
- Generate Custom shadcn/ui Themes
- Theming in shadcn UI: CSS Variables
shadcn/ui Installation und Theme-Anpassung
shadcn/ui von Grund auf installieren, Theme-System konfigurieren und markenspezifisches Design umsetzen
⏱️ Estimated time: 30 min
- 1
Step 1: Schnelle CLI-Initialisierung
In einem neuen Projekt den Installationsbefehl ausführen:
• npx shadcn@latest init
• TypeScript/New-York-Stil/Standard-Theme wählen
• Warten, bis die CLI die Konfiguration abschließt - 2
Step 2: Marken-Primärfarbe anpassen
CSS-Variablen in globals.css bearbeiten:
• app/globals.css öffnen
• --primary-Variable unter :root finden
• Auf Ihre Markenfarbe setzen (HSL- oder OKLCH-Format)
• --primary-foreground anpassen, damit der Kontrast stimmt - 3
Step 3: Dark Mode konfigurieren
next-themes installieren und konfigurieren:
• npm install next-themes
• ThemeProvider in layout.tsx einbinden
• suppressHydrationWarning setzen, um Hydration-Warnungen zu vermeiden
• Theme-Umschalt-Komponente erstellen - 4
Step 4: Komponenten-Varianten erstellen
Eigene Styles mit CVA definieren:
• class-variance-authority installieren
• variants und defaultVariants definieren
• buttonVariants() in der Komponente anwenden
• Original-shadcn-Komponente unverändert lassen
FAQ
Worin unterscheidet sich shadcn/ui von klassischen UI-Komponentenbibliotheken?
Warum empfiehlt sich die Installation von shadcn/ui gleich beim Projektstart?
Warum CSS-Variablen im nackten Format statt als Standard-HSL?
Wie ändere ich die Marken-Primärfarbe?
Warum flackert der Dark Mode beim Umschalten?
Soll ich shadcn-Komponentenquellcode direkt ändern?
7 Min. Lesezeit · Veröffentlicht am: 26. März 2026 · Aktualisiert am: 13. Juli 2026
Tailwind & shadcn/ui in der Praxis
Wenn du über die Suche hier gelandet bist, kommst du am schnellsten weiter, indem du zum vorherigen oder nächsten Beitrag dieser Serie springst.
Vorheriger
Was ist shadcn/ui? Vergleich und Auswahl: shadcn/ui vs. MUI, Chakra & Ant Design
Tiefgehender Vergleich von shadcn/ui, Material-UI, Chakra UI und Ant Design – sieben Dimensionen von Bundle-Größe über Anpassbarkeit, Developer Experience und Barrierefreiheit bis zur Entscheidungshilfe
Teil 3 von 14
Nächster
Admin-Skeleton mit shadcn/ui: Sidebar + Layout – Best Practices
Best Practices für shadcn/ui Sidebar und Next.js Layout: von Komponentenarchitektur über responsives Design bis RBAC – Schritt für Schritt ein skalierbares Admin-Skeleton mit vollständigen Codebeispielen
Teil 5 von 14
Ähnliche Beiträge
Tailwind v4 + Vite: 5-Minuten-Setup-Vorlage und Verzeichnisstruktur

Tailwind v4 + Vite: 5-Minuten-Setup-Vorlage und Verzeichnisstruktur
Tailwind CSS v4 – Neue Features: Performance, Konfiguration und Migrationsleitfaden


Kommentare
Melde dich mit GitHub an, um einen Kommentar zu hinterlassen