Communitygithub.com

shadcn-ui/ui

Migre les projets et composants React de Radix UI vers Base UI. Utilisez-le lorsque l'on vous demande de migrer depuis radix, passer à base-ui, convertir des primitives radix, ou basculer la bibliothèque de base d'un projet shadcn. Prend en charge les composants individuels et les projets entiers.

Qu'est-ce que ui ?

Ce skill automatise la migration des wrappers shadcn, des compositions Radix faites à la main et de leur code consommateur vers `@base-ui/react`, en veillant à ce que le projet reste compilable à chaque étape. Il propose une approche en deux grandes stratégies : la paire dorée via la CLI (shadcn) pour les projets utilisant un style connu (`radix-<style>`), et un moteur de transformation en secours pour le code Radix fait main ou les styles obsolètes comme `new-york`. Il gère deux modes : progressif (par défaut, migration un composant à la fois en gardant l'original jusqu'à la fin) et projet entier (sur demande). Les règles strictes incluent l'interdiction de toucher aux bibliothèques non-Radix, la traque des radisques résiduels après fusion, le signalement honnête des différences de comportement, et la génération d'un rapport détaillé par composant dans un répertoire `.migration/`. Le skill est conçu pour Cursor (agent mode) et garantit une transition fiable même sur des codebases fortement personnalisées grâce à une fusion à trois voies et une vérification systématique par typecheck et build.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/shadcn-ui/ui/tree/HEAD/skills/migrate-radix-to-base

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Migration Radix UI -> Base UI

Vous migrez les wrappers shadcn, les compositions Radix faites à la main et leurs consommateurs vers @base-ui/react, en gardant le projet compilable à chaque étape. Soyez précis ; ne devinez jamais une correspondance. Lorsqu'une propriété ou une partie ne se trouve pas dans ces fichiers de référence, vérifiez node_modules/@base-ui/react/**/*.d.ts avant de transformer, et enregistrez les lacunes dans le rapport.

Pré-vérification (toujours)

  1. npx shadcn@latest info --json (ou le lanceur du projet) : donne la base actuelle, STYLE (ex. radix-lyra), la version de tailwind, les alias, les composants installés et le gestionnaire de paquets. Fiez-vous à lui plutôt qu'à une déduction.
  2. Détectez le gestionnaire de paquets (champ packageManager / fichier de verrouillage : pnpm-lock.yaml, bun.lock, yarn.lock, package-lock.json) et utilisez-LE pour chaque installation. Ne laissez jamais un fichier de verrouillage obsolète.
  3. Exigez un arbre git propre ; travaillez sur une branche ; un commit par composant.
  4. Vérification de base AVANT de toucher aux dépendances : exécutez la vérification de type/construction du projet afin que les échecs préexistants ne vous soient jamais attribués.
  5. Installez @base-ui/react en parallèle de radix. Les paquets Radix ne sont supprimés qu'après la migration du DERNIER composant (les deux coexistent bien).

Stratégie : d'abord la paire dorée, ensuite le moteur de transformation

  • Paire dorée via la CLI (recommandé). Si le projet est shadcn avec un style connu (radix-<style>), la CLI shadcn elle-même est l'exécuteur de la paire dorée :
    1. Classez CHAQUE wrapper d'interface utilisateur D'ABORD : différenciez le fichier de l'utilisateur par rapport à son origine standard, en utilisant le style components.json LITTÉRALEMENT dans l'URL (https://ui.shadcn.com/r/styles/<style>/<component>.json, files[0].content). Cela fonctionne pour les styles préfixés (radix-nova) ET les styles historiques sans préfixe (new-york, new-york-v4, default), qui sont tous encore servis.
    2. Mode PROJET ENTIER : basculez le style components.json de radix-<style> -> base-<style> maintenant. Mode PROGRESSIF : ne basculez PAS encore (le projet est encore principalement radix ; le basculement a lieu une fois, après le dernier composant); récupérez les variantes de base directement par URL à la place (https://ui.shadcn.com/r/styles/base-<style>/<component>.json).
    3. Wrappers VIERGES, mode projet entier : shadcn add <component> --overwrite délivre la variante de base avec la résolution exacte des icônes/polices/préréglages du projet. Ne faites jamais --all --overwrite en bloc ; allez composant par composant, ou vous serez submergé par la dérive de version du registre. Mode PROGRESSIF : n'utilisez jamais --overwrite (cela détruit l'original que les consommateurs importent encore); écrivez le contenu de la variante de base récupérée dans <component>-base.tsx à la place.
    4. Wrappers PERSONNALISÉS : récupérez la variante de base et rejouez le diff de l'utilisateur dessus (leurs personnalisations doivent SURVIVRE ; --overwrite les détruirait). Implémentation mécanique qui fonctionne à grande échelle : git merge-file user.tsx radix-golden.tsx base-golden.tsx (fusion à trois voies, avec la version radix dorée comme ancêtre) résout automatiquement la plupart des fichiers ; résolvez manuellement les conflits avec les tables de référence.
    5. BALAYAGE OBLIGATOIRE des résidus sur CHAQUE fichier de paire dorée, y compris ceux qui ont fusionné "proprement" : grep -n "radix-ui\|@radix-ui\|IconPlaceholder" par fichier. Le registre réorganise parfois les fonctions entre les variantes, ce qui fait que les fusions à trois voies signalent zéro conflit tout en laissant des morceaux radix obsolètes en place. Une fusion propre n'est PAS une preuve que le fichier est propre. Ceci est plus fiable que de reconstruire des transformations ; utilisez-le chaque fois que la paire existe. Le code consommateur/application n'a pas de mécanisme CLI : migrez-le toujours à la main en vous référant à consumer-props.md.
  • Styles obsolètes (new-york, new-york-v4, default) : classement uniquement, pas de rejeu. Ceux-ci n'ont pas de contrepartie en base (il n'y a pas de base-new-york), et recibler sur une variante base- restylerait l'application de l'utilisateur. Utilisez la version radix dorée UNIQUEMENT pour détecter les personnalisations, puis exécutez le moteur de transformation sur le PROPRE fichier de l'utilisateur : reconnectez les primitives, gardez leurs classes exactes, appliquez les renommages de classes. Leur apparence reste la leur. À la fin d'une migration de projet entier avec style obsolète, SIGNALEZ (ne corrigez pas) : le nom du style indique encore radix à la CLI, donc les futurs shadcn add livreront des variantes radix ; l'utilisateur décide s'il souhaite changer de style ou ajouter manuellement.
  • Moteur de transformation (solution de secours). Code Radix fait à la main, projets non-shadcn, styles inconnus : transformez en utilisant universal-patterns.md (imports dans les DEUX formes : radix-ui et @radix-ui/react-* ; asChild -> render avec l'exemple travaillé ; Portal>Positioner>Popup ; la règle FORWARD du positionneur ; renommages de parties), les tables de propriétés par famille (overlays.md, menus.md, form-controls.md, disclosure.md, display-misc.md), class-mapping.md pour les réécritures d'attributs de données/variables CSS, et wrapper-shapes.md pour les formes cibles exactes (flèche d'info-bulle, valeurs par défaut de SubContent, anatomie de select).

Modes

Progressif (par défaut). "Migrer accordéon" = un composant, motif strangler-fig :

  1. Détectez d'abord l'état en cours : un fichier <component>-base.tsx existant, des consommateurs répartis entre les anciennes/nouvelles importations. Les fichiers SONT l'état ; reprenez, ne recommencez jamais.
  2. Si le composant importe d'autres wrappers d'interface utilisateur encore sur radix (select -> button), ARRÊTEZ et recommandez de migrer d'abord ceux-ci, de bas en haut.
  3. Écrivez la version migrée dans <component>-base.tsx (original intact ; contenu de la paire dorée récupéré par URL, ou transformé à la main, selon la stratégie ci-dessus) ; vérifiez les types. Reconnectez les consommateurs UN PAR UN (importations + les propriétés du site d'appel dans consumer-props.md) ; vérifiez les types de chacun. Lorsqu'aucun consommateur n'importe l'original : supprimez-le, renommez -base -> original, inversez les importations en arrière, vérification finale, commitez. Lorsque le DERNIER wrapper radix du projet est finalisé, basculez components.json vers base-<style> et supprimez les dépendances radix.

Projet entier (uniquement si demandé explicitement) : même travail par composant dans l'ordre des dépendances (wrappers feuilles/partagés comme button et label d'abord). Après les wrappers, balayez TOUT le code de l'application avec consumer-props.md — la surface de rupture des sites d'appel est beaucoup plus grande que asChild. Ensuite, supprimez les dépendances radix, installez, construction complète.

Règles strictes

  • NE touchez JAMAIS aux bibliothèques non-Radix ou à leurs wrappers : cmdk (commande), vaul (tiroir), sonner, input-otp, react-day-picker (calendrier), recharts (graphique). Signalez-les comme intentionnellement non touchés.
  • Pas de contrepartie dans Base UI : AspectRatio -> div avec aspect-ratio CSS ; Label -> <label> natif ; VisuallyHidden -> sr-only ; Direction -> Direction Provider (propriété direction, pas dir). Popover Anchor et NavigationMenu Indicator n'ont pas d'équivalent : passage passif + drapeau.
  • button.tsx migre vers la VRAIE primitive @base-ui/react/button, jamais un wrapper useRender fait à la main.
  • Les différences de comportement sont SIGNALÉES, jamais corrigées en silence (activation manuelle des onglets, éléments de menu qui ne se ferment pas au clic, délai de 50ms du nav-menu). La cible est un Base UI idiomatique correspondant au registre de base shadcn.
  • Rapport honnête : les fichiers ignorés/revenus sont listés comme signalés, jamais comme migrés. Les échecs préexistants sont nommés comme préexistants.

Vérifier et rapporter

Vérification des types par fichier, construction par lot, construction complète à la fin par rapport à la ligne de base.

Les rapports se trouvent dans un répertoire .migration/ à la racine du projet, UN FICHIER PAR COMPOSANT : .migration/<component>.md (ex. .migration/accordion.md). Règles :

  • Chaque exécution écrit (ou écrase complètement) le fichier pour chaque composant qu'elle a migré. Réexécuter un composant remplace son rapport ; ne touchez jamais aux fichiers des autres composants.
  • Une exécution multi-composants ("migrer alert-dialog et dropdown-menu") écrit un fichier par composant, chacun autonome ; les notes de balayage des consommateurs partagés sont répétées dans chaque fichier concerné.
  • Le mode projet entier écrit les fichiers par composant plus .migration/project.md (échange de dépendances, résumé du balayage du code applicatif, résultat final de la construction).
  • Il n'y a PAS de fichier d'index. L'état de la migration est dérivé du disque, non maintenu : analysez le répertoire d'interface utilisateur du projet (l'alias ui de shadcn info, ex. components/ui ou src/components/ui) pour les importations radix restantes lorsque l'on vous demande "que reste-t-il ?". Terminez chaque résumé d'exécution avec ce nombre dérivé ("N wrappers restent sur Radix").

Chaque .migration/<component>.md utilise EXACTEMENT cette structure (elle est documentée publiquement ; les rapports doivent correspondre) :

# <component>

<date, stratégie utilisée (paire dorée via CLI / fusion / moteur), verdict en une ligne>

## Modifié

<chaque fichier touché, avec ce qui a changé et pourquoi ; inclure fichier:ligne pour tout
  élément notable. Confirmer que le balayage des résidus est propre :
  grep -n "radix-ui\|@radix-ui" sur les fichiers de ce composant>

## Laissé de côté

<fichiers qui semblent liés mais n'ont pas été intentionnellement touchés, avec la raison
  (cmdk/vaul/sonner ne sont pas radix ; dérive sans rapport ; etc.)>

## Changements de comportement

<différences qui se compilent bien mais agissent différemment ; signalées, jamais corrigées
  (activation des onglets, fermeture au clic des menus, délais...). Section vide si aucune>

## Vérifier manuellement

<courte liste de vérification QA manuelle pour cette famille de primitives : retour de focus sur
  les dialogues, navigation clavier + saisie partielle sur les menus/select, sensation de délai d'info-bulle,
  événements de validation de curseur. Étapes concrètes, une minute de clics>

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills associés