- Pubblicato il
Cos’è shadcn/ui? Capirne scopo, vantaggi e utilizzo nelle app React moderne
- Autori
Cos’è shadcn/ui? Capirne scopo, vantaggi e utilizzo nelle app React moderne
I progetti React moderni affrontano spesso un equilibrio difficile: usare una libreria di interfacce già pronta (rapida ma poco flessibile) oppure progettare un sistema proprio (flessibile ma lento da costruire)?
È qui che entra in gioco shadcn/ui, un nuovo approccio allo sviluppo delle interfacce che offre controllo completo sul codice insieme alla cura di una libreria di componenti matura.
In questa guida esploreremo cos’è shadcn/ui, perché è diventato così popolare tra gli sviluppatori React e Next.js e come usarlo per accelerare il lavoro sull’interfaccia senza perdere flessibilità.
Cos’è shadcn/ui?
shadcn/ui (spesso scritto semplicemente shadcn) non è un pacchetto npm tradizionale o una libreria di componenti con temi come Material UI o Chakra UI.
È invece una raccolta di componenti React open source di alta qualità costruiti con:
- Tailwind CSS (per gli stili)
- Radix UI (per primitive accessibili e prive di stili)
- Lucide Icons (per icone SVG pulite e coerenti)
Ma ecco la particolarità:
Invece di installarlo come dipendenza, copi il codice sorgente effettivo di ogni componente nel tuo progetto.
Questo significa che ogni pulsante, finestra di dialogo o menu a discesa vive nella tua base di codice, modificabile, personalizzabile tramite temi e sotto il tuo controllo di versione.
Puoi considerarlo un generatore di componenti o un kit iniziale per interfacce, non una dipendenza.
Come funziona
Il progetto shadcn/ui fornisce uno strumento CLI che genera i componenti direttamente nel tuo progetto:
npx shadcn-ui@latest add button
Questo comando scarica un componente Button accessibile e già pronto e lo aggiunge nella cartella locale components/ui/. Da lì puoi personalizzarlo, cambiare le classi Tailwind, modificare le varianti o adattarlo al tuo sistema di design.
Ogni componente è semplicemente React + Tailwind + Radix, senza logica nascosta o dipendenza a runtime.
Perché gli sviluppatori usano shadcn/ui
1. Piena proprietà del codice
A differenza delle librerie di interfacce in cui fai affidamento su dipendenze opache, shadcn ti offre il sorgente completo dei componenti. Puoi:
- Modificare direttamente gli stili
- Aggiungere proprietà o varianti
- Integrare logica personalizzata (come analisi o autorizzazioni)
È la tua interfaccia, con le tue regole, senza aspettare che i manutentori integrino una PR.
2. Costruito su fondamenta collaudate
Ogni componente è costruito usando:
- Tailwind CSS → Stili basati su classi di utilità
- Radix UI → Primitive di base accessibili e prive di stili
- Lucide Icons → Icone SVG moderne
- clsx / tailwind-variants → Gestione pulita delle classi condizionali
Questo garantisce componenti accessibili e pronti per la produzione, che seguono fin da subito le buone pratiche dei sistemi di design.
3. Coerenza e velocità
Ottieni un punto di partenza bello e coerente per l’interfaccia:
- Spaziatura, tipografia e sistema di colori coerenti
- Modalità scura e temi tramite variabili CSS
- Layout e pattern interattivi pronti all’uso (menu a discesa, finestre modali, suggerimenti)
Puoi iniziare a rilasciare interfacce che sembrano progettate con cura, senza reinventare ogni componente.
4. Nessun vincolo verso il fornitore
Poiché i componenti sono semplice codice, puoi:
- Crearne un fork
- Sostituirli
- Combinarli con altre librerie
Se shadcn/ui dovesse cambiare o non bastasse più alle tue esigenze, i componenti rimarrebbero interamente tuoi.
Componenti comuni ed esempi
Ecco alcuni dei componenti più popolari di shadcn/ui e come appaiono in azione.
Esempio 1: pulsante
import { Button } from '@/components/ui/button'
export default function Example() {
return (
<div className="space-x-2">
<Button>Default</Button>
<Button variant="outline">Outline</Button>
<Button variant="destructive">Delete</Button>
</div>
)
}
Perché è ottimo:
- Varianti integrate come
outline,destructiveeghost. - Completamente personalizzabile tramite temi con i token di design di Tailwind.
- Abbastanza semplice da personalizzare senza perdere coerenza.
Comprendere le varianti del pulsante
Quando esegui:
npx shadcn-ui@latest add button
La CLI crea un file button.tsx dentro components/ui/, di solito così:
// components/ui/button.tsx
import * as React from 'react'
import { cva } from 'class-variance-authority'
import { cn } from '@/lib/utils'
const buttonVariants = cva(
'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none',
{
variants: {
variant: {
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-10 px-4 py-2',
sm: 'h-9 rounded-md px-3',
lg: 'h-11 rounded-md px-8',
icon: 'h-10 w-10',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
}
)
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}
function Button({ className, variant, size, ...props }: ButtonProps) {
return <button className={cn(buttonVariants({ variant, size, className }))} {...props} />
}
export { Button, buttonVariants }
Quindi cosa sono outline, destructive e ghost?
Sono varianti di stile predefinite in quella configurazione buttonVariants. Non devi definirle manualmente, sono incluse per impostazione predefinita nel componente generato.
Ogni variante corrisponde a un diverso schema di classi Tailwind:
| Variante | Stile visivo | Uso tipico |
|---|---|---|
default | Pulsante principale pieno (bg-primary, testo bianco) | Invito all’azione principale (ad esempio “Salva”, “Invia”). |
outline | Sfondo trasparente, bordo visibile | Azione secondaria o con minore enfasi (“Annulla”). |
destructive | Colore rosso/di pericolo (bg-destructive) | Azioni con conseguenze distruttive (“Elimina”, “Rimuovi”). |
ghost | Stile minimale, effetto delicato al passaggio del mouse | Pulsanti con poca enfasi (ad esempio icone, link secondari). |
link | Stile di un link testuale | Per la navigazione in linea all’interno del testo. |
Quindi, quando scrivi:
<Button variant="destructive">Delete</Button>
stai dicendo al componente Button di usare lo stile rosso di pericolo, perché la variante corrisponde a bg-destructive e text-destructive-foreground.
Cosa sono i “token di design di Tailwind”?
I “token di design” sono variabili con un nome per colori e spaziatura, usate in tutto il tema. In shadcn/ui, sono definiti in globals.css (o tailwind.config.js) in questo modo:
:root {
--background: 0 0% 100%;
--foreground: 222.2 47.4% 11.2%;
--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
/* etc. */
}
Tailwind li richiama poi come “token” usando la sintassi theme() o scorciatoie per le classi:
className = 'bg-primary text-primary-foreground hover:bg-primary/90'
Questi token:
- Mantengono i colori coerenti tra i componenti.
- Supportano automaticamente la modalità scura tramite variabili CSS.
- Permettono a designer e sviluppatori di condividere un unico linguaggio visivo (ad esempio “primario”, “accento”, “distruttivo”) invece di codici esadecimali grezzi.
Perché è utile
- Puoi aggiungere o modificare facilmente varianti (ad esempio
success,warning) nello stessobutton.tsx. - L’interfaccia rimane visivamente coerente poiché tutte le varianti attingono a token di design condivisi.
- Aggiornare il tema (colori, spaziatura ecc.) aggiorna istantaneamente tutti i componenti.
- È flessibile, usa le varianti integrate oppure estendile per adattarle al tuo marchio.
In breve: Quelle varianti (outline, destructive, ghost ecc.) sono stili predefiniti basati su token di design che puoi estendere o sovrascrivere. Contribuiscono a rendere i componenti shadcn/ui pronti per la produzione fin da subito, coerenti, capaci di adattarsi al tema e facilmente personalizzabili.
Esempio 2: finestra di dialogo (modale)
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog'
export default function Example() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Confirm Action</DialogTitle>
</DialogHeader>
<p>This action cannot be undone.</p>
</DialogContent>
</Dialog>
)
}
Perché è ottima: La finestra di dialogo usa internamente primitive Radix, quindi è accessibile da tastiera, compatibile con gli screen reader e responsive fin da subito.
Esempio 3: componenti di input e moduli
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
export default function LoginForm() {
return (
<form className="space-y-4">
<div>
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="you@example.com" />
</div>
<Button type="submit">Login</Button>
</form>
)
}
Puliti, minimali e facili da estendere per qualsiasi pagina di autenticazione o impostazioni.
Quando usare e quando non usare shadcn/ui
✅ Usalo quando
- Stai creando un prodotto personalizzato (SaaS, dashboard, app) e vuoi rapidamente un’interfaccia coerente.
- Hai bisogno di pieno controllo su design e accessibilità.
- Usi già Tailwind CSS e Next.js.
❌ Evitalo quando
- Preferisci un sistema di design pronto all’uso (come MUI, Chakra UI).
- Non usi Tailwind (il legame è stretto).
- Vuoi procedere estremamente in fretta senza toccare il codice dei componenti.
Per iniziare (configurazione rapida)
Installa Tailwind CSS (se non è già presente):
npx create-next-app my-app cd my-app npx tailwindcss init -pInizializza shadcn/ui
npx shadcn-ui@latest initAggiungi componenti
npx shadcn-ui@latest add button card dialog inputImporta e personalizza I nuovi componenti appariranno in
components/ui/.
🧩 shadcn e altre librerie di interfacce a confronto
| Funzionalità | shadcn/ui | Chakra UI | Material UI | Headless UI |
|---|---|---|---|---|
| Proprietà del codice | ✅ È tuo | ❌ Controllato dalla libreria | ❌ Controllato dalla libreria | ✅ È tuo |
| Stili | Tailwind | Styled System | Emotion / CSS | Tailwind |
| Accessibilità | ✅ Radix UI | ✅ | ✅ | ✅ |
| Temi | ✅ (variabili CSS + Tailwind) | ✅ | ✅ | ⚙️ Personalizzati |
| Curva di apprendimento | 🟢 Bassa | 🟢 Media | 🔴 Alta | 🟡 Media |
| Libertà di personalizzazione | 🟢 Completa | 🟡 Parziale | 🔴 Limitata | 🟢 Completa |
Punti chiave
- shadcn/ui non è un pacchetto, è un modello di componenti che copi e possiedi.
- Ottieni controllo reale, nessun vincolo e un’ottima esperienza di sviluppo.
- Costruito con Tailwind, Radix e pattern React moderni, è ideale per i team che vogliono fondamenta di design pulite, accessibili ed estendibili.
È il perfetto punto d’incontro tra “costruire tutto da soli” e “dipendere da una pesante libreria di interfacce”.