# shadcn Registry: Fremde Komponenten sicher einbinden

> So nutzt du die shadcn Registry einer fremden Bibliothek in shadcn/ui: Namespaces, Auth-Header, Vorschau per Dry Run und die Dateien, die dabei kollidieren.

- Autor: [Serban Rusu](https://wingo-ui.com/blog/authors/serban), Founder of Wingo UI
- Veröffentlicht: 13. Okt. 2026
- Kategorie: [Komponenten-Guides](https://wingo-ui.com/de/blog/category/components)
- Lesezeit: 8 Min.
- Kanonische URL: https://wingo-ui.com/de/blog/shadcn-registry-third-party-components
- Englische Fassung: https://wingo-ui.com/blog/shadcn-registry-third-party-components

## Kurz gesagt

Trag die Bibliothek in components.json unter registries als @name mit einem URL-Template ein, bei kostenpflichtigen Items zusätzlich mit einem Authorization-Header, der aus einer Umgebungsvariable gelesen wird, und installier dann mit npx shadcn@latest add @name/item. Bevor du das ausführst, zeigen dir shadcn view und add --dry-run jede Datei, die angelegt oder überschrieben wird. In einem bestehenden shadcn/ui-Projekt behältst du deine lib/utils.ts, achtest auf gleichnamige Dateien wie button.tsx und kopierst nie die Tokens einer anderen Bibliothek über deine.

Über eine shadcn Registry kommen Komponenten aus anderen Bibliotheken in ein shadcn/ui-Projekt. Du trägst die Registry in `components.json` ein, führst `npx shadcn@latest add @name/item` aus, und die CLI schreibt die Dateien, installiert npm-Pakete und holt die Items, von denen sie abhängen. Das klappt gut, bis ein fremdes Item auf einer Datei landet, die du schon hast, ein erwartetes Token fehlt oder ein nötiger Key nicht gesetzt ist. Dieses Tutorial zeigt die Seite derer, die installieren: was in einem Registry-Item steckt, wie Namespaces und Auth-Header funktionieren, wie du vorab siehst, was eine Installation ändert, was in einem bestehenden Projekt kollidiert und wann sich der Wechsel zu einer CLI lohnt, die Versionen festhält.

Alles Folgende haben wir am 13. Oktober 2026 in einer frischen Next.js-16.4-App getestet, eingerichtet mit shadcn 4.21.4 (Preset radix-nova) und unserer eigenen Registry, Wingo UI Release 1.8.0, mit Version 1.0.3 unserer CLI. Eine eigene shadcn custom registry zu bauen, ist eine andere Aufgabe. Die [Registry-Doku von shadcn](https://ui.shadcn.com/docs/registry) erklärt sie: Du beschreibst Items in einer `registry.json`, führst `shadcn build` aus und hostest das erzeugte JSON.

## Was steckt in einem Item einer shadcn Registry?

Eine JSON-Datei pro Item, im Schema `registry-item.json`, das shadcn veröffentlicht. Unser [Button](https://wingo-ui.com/components/button) liegt unter `/r/button.json`. Gekürzt auf die Felder, die bestimmen, was in deinem Projekt landet:

```bash
curl -s https://wingo-ui.com/r/button.json \
  | jq '{type, dependencies, registryDependencies, files: [.files[] | {path, type}], cssVars, envVars}'
```

```json
{
  "type": "registry:ui",
  "dependencies": ["@radix-ui/react-slot@^1.3.3", "motion@^12.43.0"],
  "registryDependencies": [
    "https://wingo-ui.com/r/utils.json",
    "https://wingo-ui.com/r/motion.json",
    "https://wingo-ui.com/r/tones.json",
    "https://wingo-ui.com/r/ui-config.json"
  ],
  "files": [{ "path": "components/ui/button.tsx", "type": "registry:ui" }],
  "cssVars": null,
  "envVars": null
}
```

- `files` enthalten den kompletten Quellcode im Feld `content`, und `path` bestimmt, wo er landet, nachdem die CLI deine Aliase angewendet hat.
- `dependencies` sind npm-Pakete, die die CLI installiert.
- `registryDependencies` sind andere Items, per Name oder URL, rekursiv aufgelöst. Hier entstehen die meisten Überraschungen: Ein Item kann einen ganzen Baum mitbringen.
- Mit `cssVars` und `css` kann ein Item CSS-Variablen und Regeln in dein Stylesheet schreiben. Unsere lassen das leer, und das wird später wichtig.
- `envVars` landen in `.env.local` oder `.env`; laut der [Schema-Doku](https://ui.shadcn.com/docs/registry/registry-item-json) werden vorhandene Variablen nicht überschrieben.

## Wie füge ich eine shadcn namespaced registry hinzu?

Du trägst sie in das components.json registries-Objekt ein, also unter den Key `registries`. Der Key jedes Eintrags ist der Namespace, und `{name}` in der URL wird zum Namen des Items. Eine Registry mit nur kostenlosen Items braucht nicht mehr:

```json
{
  "registries": {
    "@wingo-ui": "https://wingo-ui.com/r/{name}.json"
  }
}
```

Für private oder kostenpflichtige Items nimmst du die Objektform mit Header. Diese Form steht in unserer [Installations-Doku](https://wingo-ui.com/docs/installation#shadcn) für Pro-Items:

```json
{
  "registries": {
    "@wingo-ui": {
      "url": "https://wingo-ui.com/r/{name}.json",
      "headers": { "Authorization": "Bearer ${WINGO_UI_API_KEY}" }
    }
  }
}
```

Leg den Key in `.env.local` ab. Die `.gitignore` von create-next-app schließt die Datei schon aus:

```bash
# .env.local
WINGO_UI_API_KEY=wui_...
```

Laut der [Namespace-Doku von shadcn](https://ui.shadcn.com/docs/registry/namespace) funktioniert `${VAR}` in URLs, Headern und `params` und wird aus der Umgebung eingesetzt. Zwei Dinge sind uns im Test aufgefallen:

- **Keine Variable, keine Installation.** Mit der Header-Form und ohne gesetztes `WINGO_UI_API_KEY` brach `npx shadcn@latest view @wingo-ui/button` mit der Meldung `Registry "@wingo-ui" requires the following environment variables` ab, obwohl der Button kostenlos ist. Bleib bei der einfachen URL-Form, bis du einen Key hast.
- **Ein kostenpflichtiges Item ohne passenden Key** scheitert mit dem Status des Servers. `view @wingo-ui/calendar` lieferte mit der einfachen URL `Failed to fetch from registry (402)`, weil der [Calendar](https://wingo-ui.com/components/calendar) zu Wingo UI Pro gehört.

## Wie installiere ich eine Komponente über ihren Namen?

Nenn den Namespace und das Item. Mehrere Items passen in einen Befehl:

```bash
npx shadcn@latest add @wingo-ui/calendar
npx shadcn@latest add @wingo-ui/button @wingo-ui/ui-config
```

Für öffentliche Items reicht auch eine volle URL, ganz ohne Eintrag in `components.json`: `npx shadcn@latest add https://wingo-ui.com/r/button.json`. Die Namespace-Form lohnt sich, sobald du mehr als ein Item installierst. Du richtest die Authentifizierung einmal ein, und `shadcn search @wingo-ui -q "date"` durchsucht die Registry.

Die Demo unten ist der Calendar, den `add @wingo-ui/calendar` installiert.

> Live-Demo (Calendar): Klick auf einen Tag, um ihn auszuwählen, wechsle den Monat mit den Pfeilen (oder wisch auf dem Smartphone) und klick auf den Monatsnamen, um zu einem anderen Monat oder Jahr zu springen. Probier sie unter [Calendar](https://wingo-ui.com/components/calendar) aus und installier sie mit `npx wingo-ui@latest add calendar`.

## Wie prüfe ich, was eine Registry schreibt, bevor ich sie ausführe?

Mit drei Befehlen, der günstigste zuerst. Alle lesen nur die Registry und schreiben nichts.

```bash
npx shadcn@latest view @wingo-ui/button                    # Metadaten, Abhängigkeiten, Quellcode jeder Datei
npx shadcn@latest add @wingo-ui/button --dry-run           # aufgelöste Dateiliste: anlegen oder überschreiben
npx shadcn@latest add @wingo-ui/button --diff lib/utils.ts # eine Datei: deine gegen ihre
```

Am wichtigsten ist `--dry-run`, denn es löst den ganzen Abhängigkeitsbaum auf. In unserem Projekt, das schon Button und Card von shadcn/ui hatte, kam Folgendes heraus:

```text
┌ shadcn add @wingo-ui/button (dry run)
│
├ Files (6) +4 new, ~2 overwrite
│ ~ lib/utils.ts              overwrite
│ + hooks/use-media-query.ts  create
│ + lib/tones.ts              create
│ + lib/ui-config.tsx         create
│ + lib/motion.ts             create
│ ~ components/ui/button.tsx  overwrite
│
├ Dependencies (4)
│ + clsx@^2.1.1
│ + tailwind-merge@^3.7.0
│ + motion@^12.43.0
│ + @radix-ui/react-slot@^1.3.3
│
⚠ 2 files will be overwritten.
```

Ein Button, sechs Dateien, zwei davon deine. `--view <path>` gibt den Inhalt einer Datei aus, und `--diff <path>` vergleicht ihn mit deiner Version. Lies jede Zeile mit `~`, bevor du installierst, und committe vorher, damit `git diff` alles rückgängig machen kann.

## Was kollidiert in einem bestehenden shadcn/ui-Projekt?

Vier Dinge, in der Reihenfolge, in der du auf sie stößt.

### lib/utils.ts

Die meisten unserer Items hängen von einem Item `utils` ab, das `lib/utils.ts` schreibt. Die CLI fragt deshalb, ob sie die vorhandene `utils.ts` überschreiben soll. shadcn 4.21.4 hat unser Projekt mit einer einzeiligen Datei eingerichtet, `export { cn } from "cn"`; unsere ist die ältere Variante mit `clsx` und `tailwind-merge`. Antworte mit Nein. Unsere Komponenten importieren nur `cn` aus `@/lib/utils`, und der Button von Wingo UI bestand den Type-Check gegen die einzeilige Datei von shadcn.

### Gleichnamige Dateien

Stand 4.21.4 liefert shadcn/ui 62 `ui`-Items aus, und fremde Bibliotheken nutzen dieselben Namen, weil sie ebenfalls nach `components/ui` installieren. Unser Button und der von shadcn teilen sich `button.tsx`, mit unterschiedlichen APIs: Unserer hat die `variant`-Werte `solid`, `soft`, `outline`, `ghost` und `link` und nutzt `tone="danger"`, wo shadcn `variant="destructive"` verwendet.

Durch Abhängigkeiten wird das Problem größer, als es aussieht. Der Calendar hängt von unserem Button ab, also überschreibt seine Installation auch deinen Button. Antwortest du mit Nein, bleibt ein Calendar übrig, der `variant="soft"` und `radius="full"` an einen Button übergibt, der beides nicht kennt. Die [Data Table](https://wingo-ui.com/components/data-table) löst sich in 47 Items auf, sich selbst mitgezählt; 28 davon sind Dateien in `components/ui`, und 20 davon heißen genauso wie eine Komponente von shadcn/ui, von `avatar.tsx` bis `tooltip.tsx`.

Die Lösung ist ein Ordner pro Bibliothek. Zeig mit dem `ui`-Alias der zweiten Bibliothek auf einen eigenen Ordner, dann bleibt `components/ui` bei shadcn. Unser [Setup für Claude Code mit shadcn](https://wingo-ui.com/de/blog/claude-code-shadcn-mcp-setup) zeigt dieses Layout mit `components/wingo`.

### CSS-Variablen

Beide Bibliotheken definieren `--background`, `--accent`, `--radius` und andere gemeinsame Namen, mit unterschiedlicher Bedeutung:

- **`--accent`** ist in shadcn/ui ein helles Grau (`oklch(0.97 0 0)` in unserem radix-nova-Projekt) für hervorgehobene Einträge. Unser Stylesheet definiert es als orangen Farbton, und unsere Komponenten nutzen `bg-accent` nie.
- **`--radius`** ist in diesem Projekt `0.625rem`. Unserer ist `0.375rem`, für älteren Code beibehalten und gepaart mit `--radius-md: calc(var(--radius) - 2px)`, wodurch `rounded-md` 4px ergibt.

Kopierst du unsere Tokens über deine, werden die Hervorhebungen von shadcn/ui orange und seine Ecken schrumpfen. Das umgekehrte Problem tritt mit der shadcn CLI auf: Unsere Items setzen `cssVars` auf null, also fügt nichts die Tokens hinzu, die sie nutzen. Klassen wie `shadow-raised` und `z-modal` laufen dann ins Leere. Der sichere Merge ist `npx wingo-ui@latest init`. In unserem Projekt hat er 43 Variablen, 17 Dark-Werte und 43 `@theme`-Mappings ergänzt und keine bestehende Zeile geändert, also behielten `--accent` und `--radius` die Werte von shadcn. Unsere Komponenten nutzen feste Eckenradien (ein mittlerer Button ist `rounded-[10px]`), dein `--radius` ändert sie also nicht.

### Base-UI-Styles und asChild

shadcn-Styles mit dem Namen `base-*` nutzen Base UI, und die CLI schreibt `asChild` beim Installieren in den `render`-Prop von Base UI um. Wir haben `"style": "base-nova"` gesetzt und `add @wingo-ui/dialog --dry-run --view components/ui/dialog.tsx` ausgeführt: Aus `<DialogClose asChild>` wurde `<DialogClose render={<Button ... />}>`, aber unser Dialog importiert weiterhin Radix, und Radix kennt keinen `render`-Prop. In einem Base-UI-Projekt installierst du deshalb mit unserer CLI, die Dateien so schreibt, wie sie veröffentlicht sind.

## Wann lohnt sich der Wechsel von der shadcn CLI zur Wingo UI CLI?

Wenn du Updates willst. Die shadcn CLI hält nichts darüber fest, was sie installiert hat. Ein späteres Release erreicht deine Dateien also nur über `add --overwrite`, und das verwirft deine Änderungen. Unsere CLI schreibt `wingo-ui.json` mit der Version jedes Items und legt die installierte Kopie in `.wingo-ui/base` ab. Erst das macht den 3-Way-Merge von `update` möglich. Um für die Items, die du von uns installiert hast, von der CLI von shadcn/ui auf unsere umzusteigen, installierst du nichts neu:

```bash
npx wingo-ui@latest init         # wingo-ui.json, fehlende Tokens, behält lib/utils.ts
npx wingo-ui@latest add button   # festhalten, was du schon hast
npx wingo-ui@latest outdated
```

`init` übernimmt `components.json` nicht. Es liest daraus ein einziges Feld, `tailwind.css`, um dein Stylesheet zu finden, nimmt den Alias `@/*` aus `tsconfig.json` und schreibt seine eigenen Ordner in `wingo-ui.json`. Ändere dort also `aliases.ui`, wenn unsere Dateien außerhalb von `components/ui` liegen. In unserem Test fand es das `export { cn } from "cn"` von shadcn und behielt es.

`add` vergleicht danach jede Datei mit dem aktuellen Release. In unserem Projekt, in das Button und Helfer über `shadcn add @wingo-ui/button` gekommen waren, meldeten alle fünf Dateien `identical` und wurden mit 1.0.0 erfasst, und `outdated` zeigte sie als aktuell an.

Eine Datei, die du bearbeitet hast, meldet stattdessen `conflict` und wird nicht erfasst. Sichere deine Kopie, hol dir unsere mit `--overwrite` und spiel deine danach zurück:

```bash
cp components/ui/button.tsx /tmp/button.mine.tsx
npx wingo-ui@latest add button --overwrite
cp /tmp/button.mine.tsx components/ui/button.tsx
npx wingo-ui@latest diff button   # sollte nur deine Änderungen zeigen
```

Das ist exakt, wenn deine Kopie aus dem aktuellen Release stammt. Ist sie älter, zeigt `diff` auch die Upstream-Änderungen, die du nie bekommen hast, als wären es deine. Prüf sie dort.

Wenn du schon dabei bist, lager geänderte Standardwerte aus der Datei aus. Wir hatten in `button.tsx` `radius = "md"` auf `"full"` geändert; dasselbe Ergebnis als Default im [UIProvider](https://wingo-ui.com/components/ui-config) lässt die Datei unberührt, und das nächste Update hat nichts zu mergen:

```tsx
// app/providers.tsx
"use client";

import type { ReactNode } from "react";
import { UIProvider } from "@/lib/ui-config";

export function Providers({ children }: { children: ReactNode }) {
  return <UIProvider defaults={{ button: { radius: "full" } }}>{children}</UIProvider>;
}
```

Wie der Merge selbst funktioniert, samt einem Git-Skript, das dasselbe für unveränderte Dateien von shadcn/ui erledigt, steht in unserem Guide zum [Aktualisieren von shadcn-Komponenten, ohne Änderungen zu verlieren](https://wingo-ui.com/de/blog/update-shadcn-components-without-losing-edits). Die Befehle findest du auf der [Doku-Seite zu Updates](https://wingo-ui.com/docs/updates).

## Wo fange ich an?

Trag die Registry mit der einfachen URL ein, führ `npx shadcn@latest add @wingo-ui/button --dry-run` in deinem Projekt aus und lies die Liste, die dabei herauskommt. Taucht button.tsx als Überschreibung auf, wähl einen Ordner für die zweite Bibliothek, bevor du irgendetwas installierst. Calendar und Data Table gehören zu Wingo UI Pro, siehe [Preisseite](https://wingo-ui.com/de/pricing); Button und UIProvider sind kostenlos. Wie sich die beiden Bibliotheken über die Registry hinaus unterscheiden, liest du in [Wingo UI vs shadcn/ui](https://wingo-ui.com/de/blog/wingo-ui-vs-shadcn), und weitere Deep Dives findest du unter [Komponenten-Guides](https://wingo-ui.com/de/blog/category/components).

## Komponenten in diesem Artikel

- [Button](https://wingo-ui.com/components/button) (Free): The React button component every screen starts with: five variants, six tones, all sizes, and a loading state that never jumps. Installation: `npx wingo-ui@latest add button`
- [Calendar](https://wingo-ui.com/components/calendar) (Pro): A React calendar to pick one day, several days or a range, with disabled days, event dots, several months and a quick month / year jump. Installation: `npx wingo-ui@latest add calendar`
- [Data Table](https://wingo-ui.com/components/data-table) (Pro): A React data table on TanStack Table: search, filters, sorting, bulk actions, pinning, resizing, virtualization and cards on phones. Installation: `npx wingo-ui@latest add data-table`
- [UIProvider](https://wingo-ui.com/components/ui-config) (Free): A React config provider for Wingo UI: app-wide default props for every component, the Intl locale and a reduced-motion policy. Installation: `npx wingo-ui@latest add ui-config`

## Häufige Fragen

### Was ist eine shadcn Registry?

Ein Server, der Komponenten als JSON-Dateien im registry-item-Format von shadcn veröffentlicht: den Quellcode jeder Datei, die nötigen npm-Pakete und die anderen Items, von denen sie abhängt. Die shadcn CLI liest diese Dateien und schreibt den Quellcode in dein Projekt.

### Wie füge ich eine fremde Registry zu components.json hinzu?

Leg unter registries einen Eintrag an, etwa "@wingo-ui": "https://wingo-ui.com/r/{name}.json". Für private oder kostenpflichtige Items nimmst du die Objektform mit url und headers und schreibst den Key als ${VAR}, damit die CLI ihn aus der Umgebung oder aus .env.local liest.

### Warum bricht die shadcn CLI mit einem Fehler zu einer fehlenden Umgebungsvariable ab?

Eine Registry in components.json nutzt ${VAR} in ihrer URL oder ihren Headern, und die Variable ist nicht gesetzt. Setz sie in .env.local oder in deiner Shell, oder nutz die einfache URL-Form, solange du nur kostenlose Items installierst.

### Sollte eine fremde Registry meine lib/utils.ts überschreiben?

Meistens nicht. Wenn deine Datei schon cn exportiert, funktionieren Komponenten weiter, die cn aus @/lib/utils importieren. In unserem Test bestand der Button von Wingo UI den Type-Check gegen die einzeilige lib/utils.ts von shadcn, die cn aus dem Paket cn re-exportiert.

### Kann ich später von der shadcn CLI auf die CLI einer Bibliothek wechseln?

Ja. Bei Wingo UI führst du im selben Projekt npx wingo-ui@latest init aus und danach npx wingo-ui@latest add für die Items, die du installiert hast. Dateien, die dem aktuellen Release entsprechen, werden als installiert erfasst, sodass spätere Updates in sie gemergt werden können.

---

Quelle: https://wingo-ui.com/de/blog/shadcn-registry-third-party-components
