Komponentenbibliotheken vergleichen
Die Wahl der richtigen Vue 3-Komponentenbibliothek entscheidet über Accessibility, Bundle-Größe und wie viel Design-Kontrolle das Team behält. Headless UI, Radix Vue, shadcn/vue, PrimeVue und Naive UI verfolgen grundlegend verschiedene Philosophien – dieser Artikel zeigt, welche für welchen Kontext die richtige ist.
Inhaltsverzeichnis
- 1. Headless vs. Styled: die zwei Grundphilosophien
- 2. Headless UI für Vue: Accessibility ohne Stil
- 3. Radix Vue: primitive Bausteine für Composables
- 4. shadcn/vue: der Copy-Paste-Ansatz
- 5. PrimeVue: vollständige Komponentenbibliothek
- 6. Naive UI: TypeScript-first mit eigener Theming-Engine
- 7. Accessibility: der entscheidende Unterschied
- 8. Integration ins eigene Design-System
- 9. Direkter Vergleich: alle Bibliotheken auf einen Blick
- 10. Zusammenfassung
- 11. FAQ
1. Headless vs. Styled: die zwei Grundphilosophien
Der grundlegendste Unterschied zwischen Vue 3-Komponentenbibliotheken liegt nicht in der Anzahl der mitgelieferten Komponenten, sondern in der Frage, wer das visuelle Design kontrolliert. Headless Komponentenbibliotheken wie Headless UI und Radix Vue liefern nur Logik und Barrierefreiheit – kein CSS, keine Klassen, keine Styles. Das Design liegt vollständig beim Entwickler. Styled Komponentenbibliotheken wie PrimeVue, Naive UI oder Vuetify liefern fertige, visuelle Komponenten mit einem eigenen Design-System, das angepasst, aber nicht vollständig ersetzt werden kann.
Diese Philosophie hat direkte Konsequenzen für die Anpassbarkeit: Headless Bibliotheken ermöglichen maximale Design-Freiheit und passen sich nahtlos in jedes Design-System oder Tailwind-Setup ein. Styled Bibliotheken beschleunigen die Entwicklung erheblich, wenn das mitgelieferte Design ausreicht oder nur geringfügig angepasst werden muss. Zwischen diesen Polen liegt shadcn/vue: Es liefert vorgestylte Komponenten als Tailwind-CSS-Quellcode, den man direkt ins Projekt kopiert und damit vollständig besitzt. Das ist eine dritte Philosophie – nicht installiert, sondern besessen – die wachsende Beliebtheit in der Vue-Community genießt.
2. Headless UI für Vue: Accessibility ohne Stil
Headless UI von Tailwind Labs ist die bekannteste headless Komponentenbibliothek mit Vue 3-Support. Sie liefert Komponenten für die häufigsten Interaktionsmuster: Dialog, Disclosure, Listbox, Menu, Popover, RadioGroup, Switch, Tab und Transition. Jede Komponente implementiert das entsprechende ARIA-Pattern vollständig und korrekt – Tastaturnavigation, Fokusmanagement, Screenreader-Announcements sind eingebaut, ohne dass der Entwickler ARIA-Attribute manuell setzen muss.
Der Einsatz von Headless UI in Vue 3 erfordert, dass man alle visuellen Styles selbst hinzufügt – typischerweise mit Tailwind CSS. Das klingt nach Mehraufwand, ist aber der Kern des Konzepts: Die Logik (was der Button tut) ist von der Darstellung (wie er aussieht) vollständig getrennt. Für Teams, die ein eigenes Design-System haben oder Tailwind verwenden, ist Headless UI ideal. Für Teams, die schnell zu einer funktionierenden UI kommen wollen, ohne jede Komponente von Grund auf zu stylen, ist die Lernkurve zunächst steiler als bei styled Bibliotheken.
<!-- AccessibleDialog.vue — Headless UI Dialog with custom Tailwind styles -->
<template>
<TransitionRoot appear :show="isOpen" as="template">
<Dialog as="div" class="relative z-50" @close="closeModal">
<TransitionChild
as="template"
enter="duration-200 ease-out" enter-from="opacity-0" enter-to="opacity-100"
leave="duration-150 ease-in" leave-from="opacity-100" leave-to="opacity-0"
>
<!-- Overlay — styled with Tailwind, accessible via Headless UI Dialog -->
<div class="fixed inset-0 bg-black/40 backdrop-blur-sm" />
</TransitionChild>
<div class="fixed inset-0 flex items-center justify-center p-4">
<TransitionChild
as="template"
enter="duration-200 ease-out" enter-from="opacity-0 scale-95" enter-to="opacity-100 scale-100"
leave="duration-150 ease-in" leave-from="opacity-100 scale-100" leave-to="opacity-0 scale-95"
>
<!-- Dialog panel — full focus trap and ARIA management by Headless UI -->
<DialogPanel class="bg-white rounded-2xl shadow-xl p-6 max-w-md w-full">
<DialogTitle class="text-lg font-bold text-slate-900">{ { title } }</DialogTitle>
<DialogDescription class="text-sm text-slate-600 mt-2">{ { description } }</DialogDescription>
<div class="mt-6 flex gap-3 justify-end">
<button class="px-4 py-2 rounded-lg bg-slate-100 hover:bg-slate-200 text-sm font-medium" @click="closeModal">Abbrechen</button>
<button class="px-4 py-2 rounded-lg bg-green-600 text-white hover:bg-green-700 text-sm font-medium" @click="confirm">Bestätigen</button>
</div>
</DialogPanel>
</TransitionChild>
</div>
</Dialog>
</TransitionRoot>
</template>
<script setup>
import { Dialog, DialogPanel, DialogTitle, DialogDescription, TransitionRoot, TransitionChild } from '@headlessui/vue'
defineProps({ isOpen: Boolean, title: String, description: String })
const emit = defineEmits(['close', 'confirm'])
const closeModal = () => emit('close')
const confirm = () => emit('confirm')
<\/script>
3. Radix Vue: primitive Bausteine für Composables
Radix Vue ist der Vue-Port der populären Radix UI-Bibliothek aus dem React-Ökosystem. Im Gegensatz zu Headless UI, das vollständige Komponenten-Abstraktion bietet, denkt Radix Vue in Primitives: granulare, zusammensetzbare Bausteine, die man nach dem Composite-Muster kombiniert. Ein Dialog in Radix Vue besteht aus DialogRoot, DialogTrigger, DialogPortal, DialogOverlay, DialogContent, DialogTitle und DialogClose – jeder Teil ist einzeln ersetzbar und anpassbar.
Diese Granularität macht Radix Vue besonders flexibel für fortgeschrittene Anwendungsfälle: Man kann nur die Teile einer Komponente verwenden, die man braucht, und eigene Implementierungen für die anderen einsetzen. Radix Vue liefert wie Headless UI keinerlei Styles – es ist eine reine Accessibility- und Logikschicht. Der Unterschied zu Headless UI liegt in der Granularität der Abstraktion und der Breite der unterstützten Komponenten: Radix Vue deckt deutlich mehr Interaktionsmuster ab, darunter auch komplexere wie Toolbar, NavigationMenu, Accordion, Collapsible, ContextMenu und Toast.
4. shadcn/vue: der Copy-Paste-Ansatz
shadcn/vue ist kein npm-Paket im klassischen Sinne. Stattdessen kopiert man Komponenten via CLI (npx shadcn-vue@latest add button) direkt in das eigene Projekt – als Quellcode, den man vollständig besitzt und beliebig modifizieren kann. Die Komponenten bauen intern auf Radix Vue für Accessibility und Logik auf und nutzen Tailwind CSS für das Styling. Das Ergebnis: fertig gestylte, accessible Komponenten im eigenen Code, ohne dass ein npm-Update das Design verändern kann.
Der shadcn/vue-Ansatz ist besonders attraktiv für Teams, die ein konsistentes Design-System wollen, aber nicht die Ressourcen haben, alle Komponenten von Grund auf zu bauen. Man startet mit dem Standarddesign und passt die Tailwind-Klassen nach eigenem Bedarf an. Da der Code im eigenen Repository liegt, ist es kein Problem, eine Komponente grundlegend umzugestalten – es gibt keine Library-API, die man brechen könnte. Der Nachteil: Bug-Fixes und Verbesserungen aus dem shadcn/vue-Projekt muss man manuell nachziehen, da man kein Update via npm ausführen kann.
5. PrimeVue: vollständige Komponentenbibliothek
PrimeVue ist die umfangreichste styled Komponentenbibliothek für Vue 3. Mit über 90 Komponenten – von einfachen Buttons bis zu komplexen DataTables mit virtueller Scrolling, TreeSelect, FileUpload und Gantt-Charts – deckt PrimeVue Anforderungen ab, die andere Bibliotheken gar nicht erst ansprechen. Das Theming-System erlaubt es, über CSS Custom Properties und Preset-Konfigurationen das gesamte Design anzupassen. PrimeVue 4 führte Tailwind CSS-Kompatibilität über den "Tailwind"-Presets ein.
Der Einsatz von PrimeVue ist dann sinnvoll, wenn die Anwendung viele komplexe Datenkomponenten benötigt – DataTables, Charts, Kalender, Drag-and-Drop – und das Design-System des Teams flexibel genug ist, um sich an PrimeVue anzupassen. Für eine Anwendung mit einem stark individualisierten Design-System kann PrimeVue zum Kampf gegen die Library werden: Jede Anpassung kämpft gegen die eigenen Standardklassen. In solchen Fällen ist ein headless Ansatz trotz des höheren initialen Aufwands langfristig wartbarer.
6. Naive UI: TypeScript-first mit eigener Theming-Engine
Naive UI ist eine vollständige Vue 3-Komponentenbibliothek mit dem Fokus auf TypeScript-Unterstützung und einer mächtigen, programmatischen Theming-Engine. Statt CSS Custom Properties oder Tailwind nutzt Naive UI ein JavaScript-Objekt-basiertes Theme-System, das zur Laufzeit ausgewertet wird. Das ermöglicht dynamisches Theme-Switching ohne CSS-Variablen und macht Naive UI besonders attraktiv für Anwendungen, die Dark Mode oder Nutzer-konfigurierbare Themes benötigen.
Naive UI bietet exzellente TypeScript-Typen für alle Props und Events, was es für TypeScript-lastige Teams angenehm zu verwenden macht. Die Komponentenpalette ist umfangreich und deckt die meisten Enterprise-Anforderungen ab. Der Nachteil liegt in der Theming-Komplexität: Das JavaScript-basierte Theme-System ist für einfache Anpassungen weniger intuitiv als CSS-Custom-Properties-Ansätze. Für Tailwind-intensive Projekte ist Naive UI weniger geeignet, da die Bibliothek ein eigenes Styling-Paradigma mitbringt.
7. Accessibility: der entscheidende Unterschied
Accessibility – die Barrierefreiheit von UI-Komponenten – ist der Bereich, in dem sich Headless Komponentenbibliotheken wie Headless UI und Radix Vue am stärksten von einfachen HTML-Wrappers unterscheiden. Korrekte ARIA-Patterns für komplexe Widgets wie Comboboxes, DatePicker oder Trees sind schwierig und zeitaufwendig selbst zu implementieren. Das WAI-ARIA Authoring Practices Guide beschreibt dutzende Tastaturnavigations-Muster, die alle korrekt umgesetzt sein müssen, damit ein Widget für Screenreader-Nutzer nutzbar ist.
Headless UI und Radix Vue nehmen genau diese Implementierungslast ab. Sie implementieren die ARIA-Patterns aus dem WAI-ARIA-Standard korrekt und konsistent, ohne dass der Entwickler ARIA-Attribute manuell setzen oder Tastaturhandler schreiben muss. Styled Bibliotheken wie PrimeVue und Naive UI bieten ebenfalls gute Accessibility-Unterstützung, aber die Implementierungsqualität variiert je nach Komponente. Wer Barrierefreiheit als nicht-verhandelbare Anforderung hat – etwa für öffentliche Verwaltungsanwendungen oder E-Commerce-Plattformen mit Umsatzpflicht – sollte die Accessibility-Qualität jeder Komponentenbibliothek sorgfältig prüfen.
<!-- AccessibleSelect.vue — Radix Vue Select primitive with custom styling -->
<template>
<SelectRoot v-model="selected">
<SelectTrigger
class="flex items-center justify-between w-full px-4 py-2 bg-white border border-slate-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500"
aria-label="Land auswählen"
>
<SelectValue placeholder="Land wählen..." />
<SelectIcon><ChevronDownIcon class="w-4 h-4 text-slate-500" /></SelectIcon>
</SelectTrigger>
<!-- Portal renders outside DOM tree to avoid overflow clipping -->
<SelectPortal>
<SelectContent
class="bg-white border border-slate-200 rounded-xl shadow-lg p-1 z-50"
position="popper"
:side-offset="4"
>
<SelectViewport>
<SelectItem
v-for="option in options"
:key="option.value"
:value="option.value"
class="flex items-center px-4 py-2 text-sm rounded-lg cursor-pointer hover:bg-green-50 focus:bg-green-50 data-[highlighted]:bg-green-50 outline-none"
>
<SelectItemText>{ { option.label } }</SelectItemText>
<!-- Checkmark shown automatically for selected item via Radix Vue -->
<SelectItemIndicator class="ml-auto">
<CheckIcon class="w-4 h-4 text-green-600" />
</SelectItemIndicator>
</SelectItem>
</SelectViewport>
</SelectContent>
</SelectPortal>
</SelectRoot>
</template>
<script setup>
// Radix Vue handles: keyboard navigation, ARIA attributes, focus management, portal rendering
import { SelectRoot, SelectTrigger, SelectValue, SelectIcon, SelectPortal, SelectContent, SelectViewport, SelectItem, SelectItemText, SelectItemIndicator } from 'radix-vue'
const selected = defineModel()
defineProps({ options: Array })
<\/script>
8. Integration ins eigene Design-System
Die Integration einer Vue 3-Komponentenbibliothek in ein bestehendes Design-System ist die praktisch wichtigste Dimension bei der Bibliothekswahl. Headless Bibliotheken integrieren sich per Definition reibungslos: Man bringt seine eigenen Tailwind-Klassen mit. shadcn/vue startet mit Tailwind-Defaults und lässt sich durch direkte Code-Modifikation beliebig anpassen. PrimeVue und Naive UI haben eigene Theming-Systeme, die gut mit dem Design-System zusammenarbeiten können, aber einen spezifischen Integrationsaufwand erfordern.
Ein oft übersehener Aspekt bei der Design-System-Integration: Tokens. Moderne Design-Systeme definieren Farben, Abstände und Typografie als Design Tokens – entweder als CSS Custom Properties oder als Tailwind-Konfigurationswerte. Headless UI und Radix Vue verwenden diese Tokens automatisch, weil alle Styles vom Entwickler kommen. shadcn/vue nutzt CSS Custom Properties als Token-System und lässt sich damit gut an ein Token-basiertes Design-System ankoppeln. PrimeVue's eigene Token-Schicht muss mit dem eigenen Design-Token-System synchron gehalten werden – ein Aufwand, der bei größeren Projekten nicht unterschätzt werden sollte.
9. Direkter Vergleich: alle Bibliotheken auf einen Blick
Alle besprochenen Komponentenbibliotheken für Vue 3 haben ihre Daseinsberechtigung. Die Entscheidung hängt von Projektanforderungen, Team-Know-how und Design-System-Anforderungen ab. Hier ein direkter Vergleich der wichtigsten Dimensionen:
| Bibliothek | Typ | Accessibility | Tailwind-Kompatibilität | Empfohlen für |
|---|---|---|---|---|
| Headless UI | Headless | Ausgezeichnet | Native | Tailwind-Teams mit eigenem Design |
| Radix Vue | Headless Primitives | Ausgezeichnet | Native | Granulare Kontrolle, shadcn-Basis |
| shadcn/vue | Copy-Paste Styled | Sehr gut (via Radix) | Native | Schnellstart mit anpassbarem Design |
| PrimeVue | Styled (vollständig) | Gut | Via Preset möglich | Enterprise mit komplexen Datenkomponenten |
| Naive UI | Styled (TS-first) | Gut | Eigenes System | TypeScript-Teams mit dynamischem Theming |
Die Entscheidung ist selten binär. Viele Projekte nutzen shadcn/vue als Basis für die meisten Komponenten und ziehen für spezielle Anforderungen – etwa einen DateRangePicker oder eine DataTable mit vielen Features – eine spezifische Bibliothek hinzu. Wichtig ist, dass die Grundarchitektur auf einer Bibliothek basiert, die zum Design-System des Teams passt, um Theming-Konflikte zu vermeiden.
Mironsoft
Vue 3-Entwicklung mit Headless UI, Radix Vue und Design-System-Integration
Die richtige Komponentenbibliothek für euer Vue-Projekt?
Wir analysieren eure Designsystem-Anforderungen und Accessibility-Ziele und empfehlen die passende Vue 3-Komponentenstrategie – von Headless UI und Radix Vue bis shadcn/vue und PrimeVue.
Bibliotheks-Audit
Analyse bestehender UI-Stacks auf Accessibility-Lücken und Design-System-Konflikte
Headless Setup
Radix Vue oder Headless UI in euer Tailwind-Design-System integrieren – mit fertigen Basis-Komponenten
shadcn/vue Migration
Bestehende Bibliothek auf shadcn/vue migrieren – inkl. Theme-Anpassung und Barrierefreiheitsprüfung
10. Zusammenfassung
Die Wahl zwischen Headless UI, Radix Vue, shadcn/vue, PrimeVue und Naive UI ist keine Frage von besser oder schlechter, sondern von Anforderungen und Kontext. Headless Bibliotheken geben maximale Design-Freiheit und exzellente Accessibility, erfordern aber dass das Team alle Styles selbst bringt. shadcn/vue balanciert diesen Trade-off elegant: fertige, barrierefreie Komponenten als modifizierbarer Quellcode im eigenen Repository. PrimeVue und Naive UI beschleunigen die Entwicklung komplexer Datenkomponenten erheblich, erfordern aber mehr Aufwand für tiefe Design-Anpassungen.
Für Teams mit Tailwind CSS und einem eigenen Design-System ist Headless UI oder Radix Vue (direkt oder über shadcn/vue) die zukunftssicherste Wahl: keine externen Styles, volle Kontrolle, ausgezeichnete Barrierefreiheit. Für Enterprise-Anwendungen mit komplexen Datenkomponenten und weniger strikten Design-Vorgaben ist PrimeVue oder Naive UI die produktivste Option. In beiden Fällen gilt: Die Accessibility-Qualität der Bibliothek ist keine Option, sondern Grundvoraussetzung.
Vue 3 Komponentenbibliotheken — Das Wichtigste auf einen Blick
Headless Ansatz
Headless UI und Radix Vue: nur Logik und ARIA, kein CSS. Maximale Design-Freiheit, native Tailwind-Kompatibilität, ausgezeichnete Accessibility.
shadcn/vue
Copy-Paste-Ansatz: Radix Vue + Tailwind-Code direkt ins Projekt. Vollständig modifizierbar, kein npm-Update-Risiko, Barrierefreiheit by default.
Styled Bibliotheken
PrimeVue für viele Datenkomponenten, Naive UI für TypeScript-first-Teams. Eigene Theming-Systeme erfordern mehr Anpassungsaufwand für individuelle Designs.
Entscheidungskriterien
Design-Freiheit, Accessibility-Anforderungen, Tailwind-Nutzung, Komponentenkomplexität und Team-Know-how entscheiden über die richtige Wahl.