Aller au contenu principal
Développement Web · 15 min de lecture

shadcn/ui : construire une interface pro sans repartir de zéro

shadcn/ui s'est imposé comme la base UI des projets React : composants copiés dans votre code, Tailwind, accessibilité Radix. Guide et cas concrets 2026.

Par L'équipe ConsilioWEB
shadcn/ui : construire une interface pro sans repartir de zéro
Sommaire

shadcn/ui est un système de composants React que vous copiez dans votre code : pas de dépendance npm, ownership total, Tailwind CSS et Radix UI inclus.

Ce modèle radical — « copy-paste, pas install » — a propulsé shadcn/ui en tête des outils UI React en moins de deux ans. En 2026, il équipe des milliers de projets Next.js dans le monde, des startups aux équipes produit de grandes structures.

Pour une PME ou un CTO, l'enjeu est très concret. Vous obtenez une bibliothèque de composants accessibles, personnalisables et maintenables — sans subir les cassures de versions d'une dépendance externe. Votre équipe garde la maîtrise totale du code rendu.

Chez ConsilioWEB, nous intégrons shadcn/ui dans nos projets Next.js depuis son émergence. Nous avons expérimenté le theming, les cas limites et les pièges de sur-personnalisation. Cet article partage ce retour terrain : pourquoi ce choix reste le bon en 2026, comment l'installer proprement, adapter les couleurs à votre marque, et quels pièges éviter.


shadcn/ui : pourquoi tout le monde l'a adopté

En 2023, les équipes React avaient deux options dominantes. Soit une bibliothèque monolithique comme MUI ou Chakra UI, avec son système de style opaque et ses mises à jour imposées. Soit du code écrit from scratch, long et coûteux.

shadcn/ui a proposé une troisième voie. Lancé par Shadcn (employé chez Vercel), le projet s'est imposé en quelques mois comme la référence pour les projets Next.js. Fin 2023, il était déjà le dépôt GitHub le plus étoilé de l'année en JavaScript.

Pourquoi un tel engouement ? Plusieurs facteurs se combinent.

Les raisons du succès

  • Pas de package npm à subir : shadcn-ui n'existe pas dans votre package.json. Aucune dépendance à maintenir sur le cœur UI.
  • Composants lisibles et modifiables : chaque composant atterrit dans votre codebase sous forme de fichier TypeScript. Vous voyez exactement ce que fait chaque ligne.
  • Tailwind CSS en dessous : le style est déclaratif, utilitaire et facile à surcharger.
  • Radix UI comme base d'accessibilité : les primitives interactives (Dialog, Select, Tooltip…) viennent de Radix, une bibliothèque headless conforme WAI-ARIA.
  • Thème par variables CSS : couleurs, rayons de bordure et typographies sont des variables CSS globales — vous changez tout en un seul endroit.
  • Blocks prêts à l'emploi : la registry officielle propose des pages entières (tableaux de bord, formulaires complexes, sidebars) téléchargeables en une commande.

En 2026, l'écosystème s'est encore étoffé. Un serveur MCP officiel permet aux agents de développement IA — Cursor, Claude Code — de générer des composants directement depuis la registry. C'est un avantage compétitif réel pour les équipes qui travaillent en mode IA-assisté.

shadcn/ui face aux alternatives

Critère

shadcn/ui

MUI v6

Chakra UI v3

Dépendance npm (cœur)

Aucune

Oui

Oui

Personnalisation

Totale

Limitée par le système

Partielle

Accessibilité

Radix (WAI-ARIA)

Custom

Custom

Style

Tailwind + CSS vars

Emotion / sx

CSS-in-JS

Impact bundle

Minime (tree-shaking)

Important

Moyen

Mise à jour upstream

Manuelle (vous choisissez)

Automatique

Automatique

Support Tailwind 4

Natif (2026)

Non

Non

Ce tableau résume l'essentiel. shadcn/ui offre la flexibilité maximale, en échange d'une responsabilité accrue sur les mises à jour. Pour la grande majorité des projets PME, ce compromis est largement favorable.


Le modèle « copiez le code » expliqué

C'est le point qui déroute au premier abord. Une bibliothèque de composants sans bibliothèque npm — comment ça fonctionne exactement ?

Une registry de code, pas un package

shadcn/ui est une registry : un catalogue de composants hébergés en ligne, téléchargeables à la demande via la CLI. Quand vous exécutez npx shadcn@latest add button, le CLI copie le fichier button.tsx dans votre dossier components/ui/. Ce fichier vous appartient entièrement.

Les dépendances réelles de chaque composant — Radix UI, class-variance-authority, tailwind-merge — sont, elles, installées comme packages npm classiques. C'est uniquement la couche UI de haut niveau qui n'est pas une dépendance.

Conséquences pratiques de ce modèle

  1. Pas de breaking change surprise : si shadcn/ui sort une nouvelle version, vous ne la recevez pas automatiquement. Vous décidez quand migrer, composant par composant.
  2. Modification libre : vous changez la variante destructive d'un bouton ? Aucun conflit avec un package en amont.
  3. Code lisible en équipe : n'importe quel développeur comprend le composant en lisant le fichier, sans connaître une API interne opaque.
  4. Audit simplifié : vous pouvez auditer exactement ce que fait chaque composant — utile pour les projets avec des exigences de sécurité ou de conformité.
  5. Portabilité entre projets : vous copiez les composants d'un projet à l'autre sans dépendance partagée.

La contrepartie : le coût de l'ownership

La contrepartie est réelle. Quand shadcn/ui corrige un bug d'accessibilité dans un composant, vous ne recevez pas la correction automatiquement. Vous devez la reporter manuellement.

En pratique, ce coût reste faible. Les composants sont stables. Les corrections critiques sont documentées dans le changelog et relativement rares. La plupart des équipes font un check trimestriel des composants modifiés et intègrent les fixes sélectivement.

L'écosystème qui se greffe dessus

Ce modèle a inspiré d'autres outils. Des bibliothèques comme Aceternity UI (animations avancées) ou MagicUI (micro-interactions) suivent la même approche de registry copiable. La registry shadcn/ui elle-même accepte des composants tiers communautaires depuis 2024 — un écosystème qui s'auto-alimente.

En 2026, la CLI shadcn permet également d'installer des composants depuis des registries tierces avec npx shadcn@latest add <url>. Cela ouvre la porte aux composants privés partagés entre projets dans une même organisation.


Illustration : Le modèle « copiez le code » expliqué

Installation et premiers composants shadcn/ui sur Next.js

L'installation se fait en une commande. Voici la procédure complète pour un projet Next.js avec TypeScript et Tailwind CSS.

Prérequis

Votre projet doit avoir :

  • Node.js 18+
  • Next.js 14+ (App Router recommandé)
  • Tailwind CSS configuré (v3 ou v4)

Si vous utilisez Tailwind 4, vérifiez la compatibilité — le theming CSS change. Notre article sur Tailwind CSS 4 en 2026 détaille ces différences.

Initialisation du projet

1npx shadcn@latest init

Le CLI pose quelques questions interactives :

  • Style : Default ou New York (plus compact, bordures plus fines)
  • Couleur de base : zinc, slate, stone, gray ou neutral (point de départ du thème)
  • CSS variables : oui — recommandé pour le theming dynamique
  • Alias TypeScript : le chemin @/components est préconfiguré si votre tsconfig.json a les alias

La configuration atterrit dans components.json à la racine. Ne supprimez pas ce fichier — la CLI s'en sert pour chaque add ultérieur.

Ajout de composants à la demande

1npx shadcn@latest add button
2npx shadcn@latest add card
3npx shadcn@latest add input form dialog

Chaque commande copie un ou plusieurs fichiers dans components/ui/. La commande add form installe également react-hook-form et zod comme dépendances npm réelles — les seules ajoutées à votre package.json.

Structure résultante dans votre projet

1src/
2 components/
3 ui/
4 button.tsx ← vous possédez ce fichier
5 card.tsx
6 input.tsx
7 form.tsx
8 dialog.tsx
9 lib/
10 utils.ts ← contient la fonction cn()
11 app/
12 globals.css ← variables CSS du thème

La fonction cn() est centrale dans shadcn/ui. Elle fusionne des classes Tailwind sans collision en combinant clsx et tailwind-merge. Chaque composant l'utilise pour combiner les classes de base, les variantes et les overrides passés en className.

Les Blocks : des pages entières en une commande

La feature la plus impactante en 2026 est le système de Blocks. Ce sont des compositions de composants prêtes à l'emploi : tableaux de bord complets, sidebars de navigation, formulaires multi-étapes, pages d'authentification.

1npx shadcn@latest add dashboard-01
2npx shadcn@latest add login-01
3npx shadcn@latest add sidebar-07

Chaque block copie un ensemble de fichiers dans votre projet. Vous obtenez une structure responsive et accessible en moins d'une minute. C'est particulièrement utile pour les projets clients avec des délais courts.

Intégration avec les Server Actions Next.js

Pour connecter un formulaire shadcn/ui à une Server Action Next.js, la combinaison Form + react-hook-form + Zod fonctionne nativement. Vous validez côté client avec Zod, puis passez les données à l'action serveur. L'expérience utilisateur est fluide, sans rechargement de page, avec la gestion d'état et d'erreur intégrée dans useActionState.


Theming : comment appliquer votre charte sans tout casser ?

C'est la question que pose chaque projet client. shadcn/ui livre un thème générique "zinc" ou "slate". Votre marque a ses propres couleurs. Voici comment concilier les deux.

Le système de variables CSS

shadcn/ui définit ses couleurs via des variables CSS dans globals.css :

1:root {
2 --background: 0 0% 100%;
3 --foreground: 240 10% 3.9%;
4 --primary: 240 5.9% 10%;
5 --primary-foreground: 0 0% 98%;
6 --secondary: 240 4.8% 95.9%;
7 --secondary-foreground: 240 5.9% 10%;
8 --muted: 240 4.8% 95.9%;
9 --muted-foreground: 240 3.8% 46.1%;
10 --destructive: 0 84.2% 60.2%;
11 --border: 240 5.9% 90%;
12 --ring: 240 5.9% 10%;
13 --radius: 0.5rem;
14}

Ces valeurs suivent le format HSL (hue, saturation, lightness). Pour appliquer votre couleur principale, remplacez --primary par les valeurs HSL correspondantes. Les composants s'adaptent automatiquement.

En 2026, la CLI propose également le format OKLCH, plus perceptuellement uniforme. Si votre projet cible des navigateurs modernes uniquement (Chrome 111+, Firefox 116+, Safari 16.4+), préférez OKLCH pour une meilleure cohérence des dégradés et des contrastes.

Workflow pratique pour adapter le thème

Voici notre méthode chez ConsilioWEB pour adapter le thème à une charte graphique client :

  1. Extraire les valeurs HSL de chaque couleur de marque (outils : oklch.com, hslpicker.com, ou le color picker de Figma).
  2. Identifier les rôles : quelle couleur est --primary (actions principales), laquelle sert de --destructive (erreurs, suppressions).
  3. Générer le thème dark en ajustant la luminosité — fonds sombres, textes clairs. Le thème generator officiel fournit un point de départ.
  4. Vérifier le contraste avec WebAIM Contrast Checker. Le ratio minimum WCAG AA est 4.5:1 pour le texte courant.
  5. Tester les états : hover, focus, disabled, error — chaque état utilise une variation des variables.
  6. Valider --ring en particulier : c'est l'outline de focus. Souvent oublié, c'est pourtant crucial pour l'accessibilité clavier.

Ce qu'il ne faut surtout pas faire

Évitez d'appliquer des couleurs directement dans les fichiers ui/*.tsx. Si vous modifiez button.tsx pour ajouter bg-orange-500 en dur, vous sortez du système de thème. Ce changement ne fonctionnera pas en mode dark et sera perdu à la prochaine mise à jour.

Préférez toujours les variantes via className ou des variables CSS personnalisées. Sur des projets avec des transitions avancées, nous combinons shadcn/ui avec les View Transitions API 2026 pour les changements de page — sans toucher aux composants eux-mêmes.

Créer des variantes personnalisées

Pour ajouter une variante de bouton spécifique à votre projet, utilisez class-variance-authority (CVA) directement dans button.tsx :

1const buttonVariants = cva(
2 "inline-flex items-center ...",
3 {
4 variants: {
5 variant: {
6 default: "bg-primary text-primary-foreground",
7 ghost: "hover:bg-accent",
8 // Variante custom project
9 "brand-outline": "border-2 border-[--brand] text-[--brand]",
10 },
11 },
12 }
13)

Documentez chaque variante custom avec un commentaire court. Cela facilite considérablement les mises à jour futures.


Accessibilité : ce que Radix apporte gratuitement

L'accessibilité est souvent négligée jusqu'au premier audit RGAA ou WCAG. Avec shadcn/ui, vous partez avec une longueur d'avance significative.

Radix UI : headless, accessible, robuste

Radix UI est la bibliothèque de primitives qui propulse shadcn/ui. Elle implémente les patterns WAI-ARIA pour les composants interactifs complexes :

  • Dialog : focus trap automatique, fermeture par Échap, rôle dialog et aria-modal corrects
  • Select : navigation clavier complète, rôles listbox et option, recherche par frappe
  • Tooltip : délai d'apparition configurable, accessible aux claviers et lecteurs d'écran
  • Accordion : attributs aria-expanded, aria-controls, gestion du focus automatique
  • RadioGroup, Checkbox, Switch : états ARIA synchronisés avec l'état visuel
  • DropdownMenu, ContextMenu : navigation flèches, fermeture propre, aria-haspopup
  • Popover, HoverCard : positionnement automatique avec collision detection, accessible

Ces comportements sont fournis sans configuration. Radix s'en charge entièrement. Pour une PME qui veut éviter les problèmes d'accessibilité sans engager un consultant RGAA à chaque release, c'est un avantage décisif.

Les patterns Radix à comprendre

Radix utilise le pattern compose et render : les primitives sont séparées en Root, Trigger, Content, etc. Cela donne un contrôle total sur la structure HTML sans sacrifier les comportements ARIA.

1<Dialog>
2 <DialogTrigger asChild>
3 <Button>Ouvrir le formulaire</Button>
4 </DialogTrigger>
5 <DialogContent>
6 <DialogHeader>
7 <DialogTitle>Nouveau projet</DialogTitle>
8 </DialogHeader>
9 {/* votre contenu */}
10 </DialogContent>
11</Dialog>

La prop asChild mérite une attention particulière. Elle fusionne les comportements Radix avec l'élément enfant, évitant les éléments HTML imbriqués inutiles.

Ce que shadcn/ui n'assure pas automatiquement

L'accessibilité n'est pas entièrement magique. Radix gère les interactions clavier et les attributs ARIA. Mais il reste votre responsabilité de :

  • Fournir des labels : un <Input> sans <Label> associé n'est pas accessible, peu importe la bibliothèque.
  • Gérer le contraste : votre thème personnalisé peut casser les ratios WCAG.
  • Écrire des textes alternatifs pour les images et les icônes SVG.
  • Tester avec un lecteur d'écran : NVDA sur Windows, VoiceOver sur macOS, Orca sur Linux.

Pour les animations CSS que vous ajoutez, respectez toujours prefers-reduced-motion. Notre article sur les animations CSS scroll-driven en 2026 couvre ce point en détail, notamment comment appliquer la media query correctement.

Comparatif accessibilité des composants complexes

Composant

MUI v6

Chakra UI v3

shadcn/ui + Radix

Dialog / Modal

Custom, partiel

Custom, partiel

WAI-ARIA complet ✓

Select natif-like

Custom

Custom

Listbox WAI-ARIA ✓

Navigation clavier

Partielle

Partielle

Complète ✓

Focus management

Semi-auto

Semi-auto

Automatique ✓

Fermeture par Échap

Manuelle

Manuelle

Native Radix ✓


Les limites et pièges à connaître

shadcn/ui n'est pas parfait. Voici les situations concrètes où il peut vous compliquer la vie — et comment les gérer.

La divergence avec upstream

C'est le risque principal du modèle "ownership total". Dès que vous modifiez un composant, vous créez une divergence avec la version officielle. Si shadcn/ui corrige un bug dans ce composant six mois plus tard, vous devez reporter la correction manuellement.

Solution : documentez vos modifications. Un commentaire court dans le fichier suffit :

1// ConsilioWEB 2026-08: ajout variante 'ghost-primary' pour le header nav
2// Comparer avec upstream avant la prochaine mise à jour

Certaines équipes maintiennent un fichier SHADCN_CUSTOMIZATIONS.md listant les composants modifiés et les raisons. C'est une pratique simple qui économise beaucoup de temps lors des mises à jour.

La sur-personnalisation

Il est tentant de transformer chaque composant pour coller à 100 % à la maquette Figma. Résistez.

Une sur-personnalisation fragmente le système de design. Elle rend les mises à jour douloureuses et alourdit la maintenance. La règle que nous appliquons : si vous modifiez plus de 20 % du code d'un composant, créez plutôt un composant custom spécifique dans components/ — hors du dossier ui/. Vous gardez ainsi la séparation entre les composants shadcn/ui d'origine et vos propres créations.

La gestion des dépendances implicites

Certains composants installent des packages npm sans vous le signaler clairement :

  • add form → installe react-hook-form et zod
  • add date-picker → installe react-day-picker
  • add chart → installe recharts
  • add carousel → installe embla-carousel-react

Vérifiez votre package.json après chaque add. Assurez-vous que les dépendances ajoutées sont bien voulues et compatibles avec le reste du projet.

Le piège du thème partiel

Cas fréquent : l'équipe applique --primary mais oublie --ring (outline de focus) et --accent. Résultat : le focus visible des éléments interactifs prend une couleur incohérente, parfois quasi-invisible.

Créez une checklist de validation de thème avant chaque mise en production :

  1. Contraste de --primary sur --background ≥ 4.5:1
  2. Visibilité de --ring sur fond clair et sombre
  3. Lisibilité de --destructive pour les messages d'erreur
  4. Lisibilité de --muted-foreground pour le texte secondaire
  5. Apparence des états disabled sur boutons et inputs

La compatibilité Tailwind 4

Avec Tailwind CSS 4, la configuration change en profondeur. Les variables CSS de shadcn/ui doivent être déclarées dans le layer @theme plutôt que dans :root pour que Tailwind 4 les reconnaisse comme tokens de design.

La documentation officielle shadcn/ui couvre cette migration. Vérifiez toutefois la date du guide que vous suivez — les tutoriels antérieurs à 2025 ne couvrent pas Tailwind 4 et peuvent induire en erreur.

La sur-abstraction par wrapping

Un dernier piège, plus subtil. Certains développeurs wrappent chaque composant shadcn/ui dans un composant maison supplémentaire pour ajouter des props custom. Résultat : deux couches d'abstraction pour chaque élément UI.

Avant de créer un wrapper, demandez-vous si className ne suffit pas. shadcn/ui est déjà très composable. La sur-abstraction nuit à la lisibilité sans apporter de valeur réelle.


Questions fréquentes sur shadcn/ui

shadcn/ui est-il compatible avec React 19 ?

Oui, shadcn/ui est compatible avec React 19 depuis début 2025. Les composants ont été mis à jour pour supprimer les dépendances sur les APIs dépréciées — notamment forwardRef, remplacé par la prop ref directe. Si vous utilisez des composants copiés avant cette date, vérifiez ceux qui utilisaient React.forwardRef() et mettez-les à jour manuellement. La migration est courte composant par composant.

Peut-on utiliser shadcn/ui sans Tailwind CSS ?

Non, pas nativement. shadcn/ui repose sur Tailwind pour tout le style. Des forks communautaires proposent des versions CSS Modules ou CSS classique, mais ils ne sont pas maintenus par l'équipe officielle et sont souvent en retard sur les nouvelles fonctionnalités. Si votre projet n'utilise pas Tailwind, la migration représente un effort significatif — estimez-le avant de vous lancer.

shadcn/ui est-il adapté à un projet Payload CMS + Next.js ?

Oui, c'est même une combinaison que nous recommandons. Dans les projets qui associent Payload CMS et Next.js — voir notre comparatif headless CMS 2026 — shadcn/ui équipe les interfaces front : dashboards clients, formulaires de contact, espaces membres. L'intégration est transparente. Payload gère le contenu et l'API, Next.js le rendu, shadcn/ui les composants UI.

Comment mettre à jour un composant quand shadcn/ui évolue ?

Il n'y a pas de commande upgrade globale. Vous relancez npx shadcn@latest add <composant> et vous choisissez d'écraser ou non le fichier existant. Si vous avez modifié le composant, comparez les différences avec un git diff avant d'écraser. Une bonne pratique : maintenir un dossier components/ui/base/ pour les composants non modifiés, et components/ui/ pour les versions personnalisées. Vous pouvez ainsi diffier proprement les deux versions lors des mises à jour.

Le serveur MCP shadcn/ui fonctionne-t-il avec tous les agents IA ?

Oui. Le serveur MCP officiel shadcn/ui fonctionne avec tous les outils compatibles MCP en 2026 : Cursor, Claude Code, Windsurf et d'autres. Une fois configuré, l'agent liste les composants disponibles, récupère leur code source et les insère directement dans votre projet. C'est une fonctionnalité qui accélère significativement le travail sur des projets avec de nombreux composants UI à créer.


Construire avec shadcn/ui : le bon choix en 2026

shadcn/ui a changé la façon de construire des interfaces React. Ce n'est pas une tendance passagère : le modèle « copiez le code » répond à un besoin réel d'ownership et de maintenabilité que les bibliothèques traditionnelles ne satisfaisaient pas pleinement.

En résumé, voici ce que vous gagnez en l'adoptant :

  • Des composants accessibles grâce à Radix, sans configuration supplémentaire
  • Un thème entièrement contrôlable via des variables CSS
  • Zéro dépendance npm sur le cœur de votre UI
  • Une compatibilité native avec Next.js, App Router et Server Actions
  • Un écosystème de Blocks et un MCP qui accélèrent le développement IA-assisté
  • Un code UI compréhensible par toute l'équipe, sans magie interne

Pour les PME et les équipes techniques qui veulent avancer vite sans compromis sur la qualité, c'est aujourd'hui le point de départ le plus solide pour une interface React.

Vous envisagez d'intégrer shadcn/ui dans votre prochain projet Next.js, ou de refondre l'interface d'une application existante ? Notre équipe à Ussel accompagne les PME et les CTO dans ces choix d'architecture — de l'audit de l'existant à la mise en production. Contactez-nous via le formulaire de devis pour estimer votre projet.


Pour aller plus loin

Partager
Un projet en tête ?Discutons de votre projet web et transformons vos idées en réalité.
Devis gratuit →