Zum Inhalt springen
    WingoUI
    KomponentenVorlagenDokuPreiseKI-AgentenBlogChangelog
    1. Startseite
    2. Blog
    3. Next.js und Tailwind CSS
    4. shadcn Vite Setup mit Tailwind CSS v4 und React 19
    Read in English
    1. Blog
    2. Next.js und Tailwind CSS
    3. shadcn Vite Setup mit Tailwind CSS v4 und React 19
    Next.js und Tailwind CSS
    Next.js und Tailwind CSS

    shadcn Vite Setup mit Tailwind CSS v4 und React 19

    SR
    Serban Rusu · Gründer von Wingo UI
    13. Okt. 2026 · 7 Min. Lesezeit

    Auf dieser Seite

    0%
    1. Was braucht ein Vite-Projekt für Komponenten im shadcn-Stil?
    2. Wie läuft ein shadcn Vite Setup Schritt für Schritt?
      1. 1. Projekt anlegen und Tailwind installieren
      2. 2. Plugin und Vite Path Alias ergänzen
      3. 3. tsconfig.app.json paths setzen, ohne baseUrl
      4. 4. init ausführen
      5. 5. Komponenten hinzufügen
    3. Wie bekomme ich Dark Mode in Vite ohne Next.js?
    4. Kann ich in Vite stattdessen die shadcn CLI nutzen?
      1. Das Setup, das funktioniert hat: ein Ordner pro Bibliothek
    5. Was prüfe ich, wenn etwas kaputtgeht?
    6. Nächster Schritt
    7. Häufige Fragen
      1. Funktioniert shadcn mit Vite?
      2. Warum meldet tsc in Vite, dass es das Modul @/components/ui/button nicht findet?
      3. Soll ich baseUrl in tsconfig.app.json eintragen?
      4. Kann ich next-themes in einer Vite-App nutzen?
      5. Kann ich Wingo-UI-Komponenten in Vite mit der shadcn CLI installieren?

    Kurz gesagt

    Leg die App mit npm create vite@latest -- --template react-ts an, installier tailwindcss und @tailwindcss/vite, setz den @-Alias in vite.config.ts und als paths in tsconfig.json und tsconfig.app.json (kein baseUrl unter TypeScript 6), dann führ npx wingo-ui@latest init aus und füg Komponenten hinzu. Dark Mode braucht eine .dark-Klasse am html-Element: ein kurzes Script in index.html plus den Provider von next-themes, der auch ohne Next.js läuft. In einem Projekt, das schon mit der shadcn CLI eingerichtet ist, bekommt die zweite Bibliothek einen eigenen Ordner, damit sich die beiden button.tsx-Dateien nie in die Quere kommen.

    Veröffentlicht am 13. Okt. 2026

    Die meisten Anleitungen zum shadcn Vite Setup wurden für Vite 5 und TypeScript 5 geschrieben, und zwei ihrer Schritte funktionieren heute nicht mehr. Das aktuelle Vite-Template bringt TypeScript 6 mit, das baseUrl ablehnt. Außerdem prüft es deinen Code über tsconfig.app.json, ein Alias nur in tsconfig.json kommt dort also nie an. Dieser Guide richtet ein Projekt mit Vite, React 19 und Tailwind CSS v4 ein, das Komponenten im shadcn-Stil aufnimmt. Danach installierst du sie mit der Wingo UI CLI oder der shadcn CLI, jeweils mit ihren Vor- und Nachteilen.

    Alles hier haben wir am 13. Oktober 2026 ausgeführt, mit create-vite 9.2.1 (Vite 8.3.4, React 19.3.0, TypeScript 6.0.3), Tailwind CSS 4.3.3, der wingo-ui CLI 1.0.3, der shadcn CLI 4.21.4 und next-themes 0.4.6. Die Next.js-Variante dieses Setups findest du im Guide zum Next.js Component Library Setup.

    Was braucht ein Vite-Projekt für Komponenten im shadcn-Stil?

    Komponenten, deren Quellcode dir gehört, sind einfache .tsx-Dateien. Sie importieren sich gegenseitig über einen Alias, stylen sich mit Tailwind-Utilities und lesen Farben aus CSS-Variablen. Ein Vite Tailwind v4 React Projekt braucht dafür fünf Dinge:

    BausteinWoWozu
    React 19package.jsonref als Prop, kein forwardRef
    Tailwind CSS v4Plugin @tailwindcss/vite, @import "tailwindcss";die Utilities und @theme
    @-Alias für Vitevite.config.tsdamit der Bundler @/components/ui/button auflöst
    @-Alias für TypeScripttsconfig.json und tsconfig.app.jsondamit Type Checker und Editor ihn auflösen
    Tokens und cnsrc/index.css, src/lib/utils.tsFarben, Radius, Motion, Klassen zusammenführen

    Wie läuft ein shadcn Vite Setup Schritt für Schritt?

    1. Projekt anlegen und Tailwind installieren

    bash
    npm create vite@latest my-app -- --template react-ts
    cd my-app
    npm install tailwindcss @tailwindcss/vite
    npm install -D @types/node

    In create-vite 9.2.1 steht @types/node bereits im Template. Eine zweite Installation schadet nicht, und ältere Templates brauchen das Paket für path in der Config.

    Ersetz den gesamten Inhalt von src/index.css durch eine Zeile und lösch src/App.css samt Import in src/App.tsx. Das Starter-CSS stylt #root, h1 und body und würde mit den Komponenten kollidieren.

    css
    @import "tailwindcss";

    2. Plugin und Vite Path Alias ergänzen

    ts
    // vite.config.ts
    import path from "node:path"
    import tailwindcss from "@tailwindcss/vite"
    import react from "@vitejs/plugin-react"
    import { defineConfig } from "vite"
    export default defineConfig({
    plugins: [react(), tailwindcss()],
    resolve: { alias: { "@": path.resolve(__dirname, "./src") } },
    })

    Dieser Vite Path Alias gilt nur für den Bundler. TypeScript liest vite.config.ts nicht, es braucht also eine eigene Kopie.

    3. tsconfig.app.json paths setzen, ohne baseUrl

    Die tsconfig.json des Templates hat "files": [] und zwei Referenzen. Dein src wird über tsconfig.app.json geprüft. Trag den Alias in beide Dateien ein:

    json
    // tsconfig.json
    {
    "files": [],
    "compilerOptions": { "paths": { "@/*": ["./src/*"] } },
    "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
    ]
    }
    json
    // tsconfig.app.json, innerhalb von compilerOptions
    "types": ["vite/client", "node"],
    "paths": { "@/*": ["./src/*"] },

    Drei Details, jedes aus einem fehlgeschlagenen Durchlauf:

    • Paths nur in tsconfig.json reichen nicht. Wir haben wingo-ui init den Alias selbst eintragen lassen. Es schrieb ihn in tsconfig.json, und tsc -b scheiterte danach mit Cannot find module '@/components/ui/button', weil tsconfig.app.json ihn nie gesehen hat.
    • Kein baseUrl unter TypeScript 6. Mit "baseUrl": "." in tsconfig.app.json brach tsc -b mit Fehler TS5101 ab: Die Option ist veraltet und funktioniert ab TypeScript 7 nicht mehr. paths löst ohne sie relativ zur Config-Datei auf.
    • node in types aufnehmen. Das Template beschränkt die globalen Typen auf vite/client. Manche Komponenten lesen process.env.NODE_ENV, um Warnungen in der Entwicklung auszugeben (Theme Toggle macht das), und ohne den Eintrag meldet tsc den Fehler Cannot find name 'process'. Vite ersetzt den Ausdruck beim Build: In unserem Production-Bundle war kein process.env mehr übrig.

    4. init ausführen

    bash
    npx wingo-ui@latest init

    init erkannte vite, fand den Alias in tsconfig.app.json (die CLI folgt der references-Liste) und meldete alias @/* -> src/. Danach legte es src/lib/utils.ts mit cn an, installierte clsx und tailwind-merge, führte die Tokens in src/index.css zusammen, mit einem .dark-Block und @custom-variant dark (&:is(.dark *));, und schrieb wingo-ui.json.

    Steht react-router oder @react-router/dev in package.json, speichert init als Framework react-router statt vite, weil es zuerst nach React Router sucht. Dateipfade und Befehle bleiben gleich.

    5. Komponenten hinzufügen

    bash
    npx wingo-ui@latest add button card dialog

    Die kostenlosen Items installierst du ohne Account. Die Dateien landen in src/components/ui, src/hooks und src/lib, zusammen mit den npm-Paketen, die sie importieren. Gib der Seite ihre Farben in index.html, denn das Starter-CSS, das body gestylt hat, ist weg:

    html
    <body class="bg-background text-foreground antialiased">

    Dann nutzt du sie:

    tsx
    // src/App.tsx
    import { Button } from "@/components/ui/button"
    import { Card } from "@/components/ui/card"
    import { Dialog, DialogClose } from "@/components/ui/dialog"
    export default function App() {
    return (
    <main className="mx-auto flex max-w-md flex-col gap-6 p-6">
    <Card
    title="Pro-Tarif"
    description="Verlängert sich am 1. November."
    footer={
    <Dialog
    trigger={<Button variant="soft">Tarif kündigen</Button>}
    title="Tarif wirklich kündigen?"
    description="Pro bleibt dir bis zum Ende des Abrechnungszeitraums erhalten."
    footer={
    <>
    <DialogClose asChild>
    <Button variant="soft">Tarif behalten</Button>
    </DialogClose>
    <Button tone="danger">Tarif kündigen</Button>
    </>
    }
    />
    }
    />
    </main>
    )
    }

    npm run build (das vorher tsc -b ausführt) lief mit dieser Datei durch. Button, Card und Dialog tragen "use client" ganz oben, für den Next.js App Router. Vite ignoriert die Direktive. Drück den Button unten, um seinen Ladezustand zu sehen.

    Klick auf den Button: Er zeigt kurz einen Spinner und behält seine Breite, nichts daneben verrutscht
    $ npx wingo-ui@latest add button
    FreeDoku: Button

    Wie bekomme ich Dark Mode in Vite ohne Next.js?

    Die Komponenten folgen einer .dark-Klasse am <html>-Element. Irgendetwas muss sie vor dem ersten Paint setzen, und irgendetwas muss sie ändern, wenn der Nutzer ein Theme wählt. Unser Guide zu Tailwind v4 Dark Mode erklärt die @custom-variant-Zeile, auf die sich die Komponenten verlassen.

    Vor dem Paint: Ein Script in index.html, im <head>, liest die gespeicherte Wahl und die Systemeinstellung:

    html
    <script>
    try {
    const theme = localStorage.getItem("theme")
    const dark = theme === "dark" || (theme !== "light" && matchMedia("(prefers-color-scheme: dark)").matches)
    document.documentElement.classList.toggle("dark", dark)
    } catch {}
    </script>

    Beim Wechsel: next-themes. Trotz des Namens hängt Version 0.4.6 nur von React ab, und sie speichert die Wahl unter demselben Schlüssel theme, den das Script liest:

    tsx
    // src/main.tsx
    import { StrictMode } from "react"
    import { createRoot } from "react-dom/client"
    import { ThemeProvider } from "next-themes"
    import { UIProvider } from "@/lib/ui-config"
    import "./index.css"
    import App from "./App"
    createRoot(document.getElementById("root")!).render(
    <StrictMode>
    <ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
    <UIProvider locale="en-US">
    <App />
    </UIProvider>
    </ThemeProvider>
    </StrictMode>,
    )

    Wir haben den Production-Build mit Playwright in Chromium in beiden Farbschemata geladen. Bevorzugte das System Dark Mode, stand die Klasse dark schon am <html>, bevor React startete. Der Theme Toggle schaltete sie um, und localStorage behielt die Wahl. UIProvider ist optional: Er setzt app-weite Standardwerte für Komponenten und die Locale für Datums- und Zahlenformate.

    Was in der Bibliothek nutzt next-themes? Stand 13. Oktober 2026 importiert nur theme-toggle.tsx das Paket, und die CLI installiert es mit diesem Item. Theme Toggle (Pro) akzeptiert auch value und onValueChange, falls du das Theme lieber in deinem eigenen State hältst. Dann setzt dein Code die Klasse. Drei Navigationskomponenten, Bounce Sidebar, Hook Sidebar und Gooey Nav, importieren next/link und brauchen deshalb Next.js. Alles andere läuft unverändert in Vite.

    Kann ich in Vite stattdessen die shadcn CLI nutzen?

    Ja, mit Grenzen, die du vorher kennen solltest. Wir haben npx shadcn@latest init -t vite -b radix -p nova in einem frischen Projekt nach Schritt 3 ausgeführt. Wähl Radix: Die Installations-Doku weist darauf hin, dass die Base-UI-Styles asChild umschreiben, und darauf verlassen sich diese Komponenten. Init 4.21.4 schrieb components.json, src/lib/utils.ts und eine eigene src/components/ui/button.tsx.

    Kostenlose Wingo-UI-Items installierst du über ihre URL:

    bash
    npx shadcn@latest add https://wingo-ui.com/r/dialog.json

    Die CLI fragte, ob sie utils.ts und danach button.tsx überschreiben soll. Bei utils.ts antwortest du mit Nein: Die shadcn-Version exportiert cn aus dem Paket cn weiter, einem direkten Ersatz für clsx plus tailwind-merge, und unsere Dateien brauchen nur einen cn-Export. Und hier liegt der Haken. Behältst du den Button von shadcn, besteht unser Dialog den Type Check nicht mehr, weil er Props wie radius übergibt, die der shadcn-Button nicht kennt. Überschreibst du ihn, brechen stattdessen shadcn-Komponenten, die dessen API brauchen: Der Calendar von shadcn importiert buttonVariants, und unser Button exportiert das nicht. Die shadcn CLI hat außerdem unsere Tokens nicht in src/index.css eingetragen, und sie speichert keine Versionen. wingo-ui update kann spätere Releases deshalb nicht in diese Dateien mergen.

    Für Pro-Items trägst du laut Doku den Namespace @wingo-ui in components.json ein, mit deinem Key in einer Umgebungsvariable, und führst dann npx shadcn@latest add @wingo-ui/calendar aus. Diesen Weg haben wir für diesen Artikel nicht mit einem Key getestet.

    Das Setup, das funktioniert hat: ein Ordner pro Bibliothek

    Im selben shadcn-Projekt haben wir npx wingo-ui@latest init ausgeführt. Es ergänzte nur die 43 Token-Namen, die shadcn nicht definiert hatte. Dann haben wir "ui" in wingo-ui.json auf "@/components/wingo" geändert und npx wingo-ui@latest add dialog ausgeführt. Unsere Dateien landeten in src/components/wingo, ihre Imports wurden passend umgeschrieben, die button.tsx von shadcn blieb unangetastet, und tsc -b lief durch. Die CLI-Doku beschreibt die übrigen Aliase.

    Was prüfe ich, wenn etwas kaputtgeht?

    FehlerUrsacheLösung
    Cannot find module '@/...' von tsc -bAlias fehlt in tsconfig.app.jsondort paths ergänzen (Schritt 3)
    TS5101: Option 'baseUrl' is deprecatedbaseUrl unter TypeScript 6entfernen, paths behalten
    Cannot find name 'process'types auf vite/client beschränkt"node" zu types hinzufügen
    Dark Mode blitzt beim Neuladen hell aufkein Script in index.htmldas Script vor dem Paint ergänzen
    Komponenten ohne StylesTokens fehlen in src/index.cssnpx wingo-ui@latest init erneut ausführen

    Nächster Schritt

    Führ npx wingo-ui@latest add button card dialog in deinem neuen Projekt aus und öffne die Installations-Doku für den manuellen Weg. Das Token-System hinter all dem erklärt der Pillar-Artikel zu Tailwind v4 Design Tokens. Weitere Setup-Guides findest du unter Next.js und Tailwind CSS, darunter das Next.js Component Library Setup, falls du das Projekt auf den App Router umstellst.

    Komponenten in diesem Artikel

    • Button

      The React button component every screen starts with: five variants, six tones, all sizes, and a loading state that never jumps.

      Free
    • Card

      A React card component for listings, stats, settings and plans: media, header, body and footer parts, and a lift-and-press mode.

      Free
    • Dialog

      A React modal dialog for focused tasks: a spring-scaled card on desktop and a bottom sheet on phones, with nesting and scrolling.

      Free
    • UIProvider

      A React config provider for Wingo UI: app-wide default props for every component, the Intl locale and a reduced-motion policy.

      Free

    Häufige Fragen

    Funktioniert shadcn mit Vite?

    Ja. shadcn-Komponenten sind Quelldateien aus React und Tailwind ohne Abhängigkeit zu Next.js. Vite braucht das Plugin @tailwindcss/vite, einen @-Alias in vite.config.ts und passende paths in tsconfig.app.json.

    Warum meldet tsc in Vite, dass es das Modul @/components/ui/button nicht findet?

    Das Vite-Template prüft src über tsconfig.app.json, eine Referenz von tsconfig.json. Paths, die nur in tsconfig.json stehen, kommen dort nicht an. Trag denselben paths-Eintrag für den @-Alias mit Ziel ./src deshalb auch in tsconfig.app.json ein.

    Soll ich baseUrl in tsconfig.app.json eintragen?

    Nicht unter TypeScript 6, das das Vite-Template Stand Oktober 2026 installiert. tsc -b bricht dann mit Fehler TS5101 ab, weil baseUrl veraltet ist, und paths funktioniert auch ohne.

    Kann ich next-themes in einer Vite-App nutzen?

    Ja. next-themes 0.4.6 nennt nur react und react-dom als Peer Dependencies. Umschließ die App mit ThemeProvider und attribute="class" und ergänz ein kleines Script in index.html, damit die Klasse vor dem ersten Paint gesetzt ist.

    Kann ich Wingo-UI-Komponenten in Vite mit der shadcn CLI installieren?

    Kostenlose Items installierst du über ihre URL, zum Beispiel npx shadcn@latest add https://wingo-ui.com/r/dialog.json (opens in a new tab). Die shadcn CLI ergänzt aber keine Wingo-UI-Tokens und speichert keine Versionen, und eine button.tsx von shadcn kollidiert mit unserer. Der bequemere Weg ist deshalb die Wingo UI CLI mit eigenem Ordner.

    • Vite
    • shadcn/ui
    • Setup
    • Installation
    • Tailwind CSS v4

    Teilen

    SR

    Über den Autor

    Serban Rusu

    Gründer von Wingo UI

    Serban Rusu hat Wingo UI gegründet. Er baut die Komponenten, die CLI und den MCP-Server und schreibt über React-UIs für Smartphones und KI-Agents.

    Mehr von Serban
    Weiterlesen

    Ähnliche Artikel

    Alle Artikel
    Next.js und Tailwind CSS

    Next.js Component Library im App Router einrichten

    Next.js Component Library im App Router einrichten, getestet mit Next.js 16.4: use client, Tokens in globals.css, Dark Mode ohne Flackern, Updates per CLI.

    SRSerban Rusu·13. Okt. 2026·8 Min. Lesezeit
    Next.js und Tailwind CSS

    Tailwind v4 Design Tokens: Farben, Dark Mode, Kontrast

    Tailwind v4 Design Tokens aus einer produktiven React-Bibliothek: @theme inline, semantische Flächen, Statusfarben, Dark Mode und ein Kontrast-Check für CI.

    SRSerban Rusu·9. Okt. 2026·20 Min. Lesezeit
    UI mit KI-Agenten bauen

    AGENTS.md vs CLAUDE.md vs Cursor-Regeln für React

    AGENTS.md vs CLAUDE.md vs Cursor-Regeln für React und Tailwind: wer welche Datei liest (Oktober 2026) und eine Regeldatei, die Agenten bei deinen Tokens hält.

    SRSerban Rusu·9. Okt. 2026·14 Min. Lesezeit
    Newsletter

    Neue Artikel per E-Mail

    Neue Guides, Tutorials und Vergleiche aus dem Wingo UI Blog, sobald sie erscheinen. Die meisten Artikel sind auf Englisch.

    Kein Spam. Du kannst dich jederzeit abmelden.

    WingoUI

    Animierte, konfigurierbare, mobile-first React-Komponenten und Blöcke. Kopier den Quellcode, pass ihn an und lass deinen Coding-Agenten damit bauen.

    Produkt

    • Komponenten
    • Vorlagen
    • Preise
    • KI-Agenten
    • Theme-Generator

    Ressourcen

    • Doku
    • Blog
    • Changelog
    • Changelog-RSS
    • llms.txt

    Rechtliches

    • AGB
    • Datenschutz
    • Rückerstattung
    • Lizenz
    • Impressum

    Komponenten-Kategorien

    • Buttons & Actions
    • Inputs
    • Forms
    • Navigation
    • Overlays
    • Feedback
    • Data Display
    • Tables & Lists
    • Charts & Stats
    • Layout
    • Media
    • AI Kit
    • Text & Effects
    • Mobile
    • Commerce
    • Marketing Sections
    • Blocks
    • Hooks & Utilities

    © 2026 Wingo UI

    Wingo UI