shadcn/ui

by shadcn

How it's built

#Color system

shadcn/ui doesn't generate a palette. It ships a fixed set of semantic CSS variables — borrowed from Tailwind's color scales — that you re-theme by swapping values. In v4 those values are OKLCH.

Every surface has a foreground

Tokens come in pairs: a surface color and the -foreground meant to sit on it. Components reference the pair (bg-primary text-primary-foreground), so a re-theme never breaks contrast.

Aabackground · foreground
Aacard · card-foreground
Aaprimary · primary-foreground
Aasecondary · secondary-foreground
Aamuted · muted-foreground
Aaaccent · accent-foreground

Light and dark

Values are defined once, then overridden under .dark. The token names never change — only what they resolve to.

lightPrimary
darkPrimary

One real choice: the neutral base

The grays are the only thing you pick up front. Each base tints every neutral token toward a hue; the semantic structure is identical across all five.

Neutral
Stone
Zinc
Gray
Slate

Explore

#Colors

Every token resolved for the picks a shadcn user actually makes — base gray, color theme, and mode. Watch the same UI re-theme, and see the exact Tailwind step behind each value (borrowed steps highlighted).

Live preview

Create project
Deploy your new project in one click.
Muted note — secondary text sits here.
PrimaryAccent
TokenValueTailwind
Surfaces
backgroundwhite
foregroundzinc-950
cardwhite
card-foregroundzinc-950
popoverwhite
popover-foregroundzinc-950
Semantic roles
primaryzinc-900
primary-foregroundzinc-50
secondaryzinc-100
secondary-foregroundzinc-900
mutedzinc-100
muted-foregroundzinc-500
accentzinc-100
accent-foregroundzinc-900
destructivered-600
Borders & focus
borderzinc-200
inputzinc-200
ringzinc-400
Charts
chart-1zinc-300
chart-2zinc-500
chart-3zinc-600
chart-4zinc-700
chart-5zinc-800
Sidebar
sidebarzinc-50
sidebar-foregroundzinc-950
sidebar-primaryzinc-900
sidebar-primary-foregroundzinc-50
sidebar-accentzinc-100
sidebar-accent-foregroundzinc-900
sidebar-borderzinc-200
sidebar-ringzinc-400

What gets borrowed

Almost every token is the base gray. A handful reach outside it — and that's the whole of shadcn's color choices.

  • destructive is always red; in dark mode border and input are translucent white, and sidebar-primary is blue.
  • neutral/stone/zinc tint the charts to their own gray; gray/slate keep Tailwind's colorful default series.
  • A color theme repaints primary, ring, and their sidebar twins with a colored step — everything else stays the base gray. (The ring is a lighter/darker shade than the primary, and shadcn's “green” is built on lime.)

Every value is an exact Tailwind step — the base grays and the color themes alike (shadcn annotates each in its own source). Highlighted chips are the steps that reach outside the chosen base gray.

Explore

#Usage

Beyond the declared tokens, shadcn's component styles derive colours at the point of use — token opacity modifiers, color-mix blends, and relative-oklch tints. These are extracted from style-nova, shadcn's default style, so you can see exactly where each derivation is used.

36 expressions

Colours that exist only at point of use in component styles — opacity-modified tokens, color-mix, and relative-oklch tints. Extracted from style-nova, shadcn’s default style.

Opacity

opacity28 expressions
PreviewExpressionUsed by
bg-background/10
bg-background/20
bg-destructive/10
bg-destructive/20
bg-destructive/30
bg-foreground/10
bg-foreground/5
bg-input/30
bg-input/50
bg-input/80
bg-muted/50
bg-popover/70
bg-primary/10
bg-primary/5
bg-primary/80
bg-secondary/80
border-border/50
border-destructive/40
border-destructive/50
border-input/30
border-primary/20
border-primary/30
ring-destructive/20
ring-destructive/40
ring-foreground/10
ring-ring/50
text-destructive/90
text-sidebar-foreground/70

Color-mix

color-mix2 expressions
PreviewExpressionUsed by
bg-[color-mix(in oklch,var(--muted),var(--foreground) 5%)]
bg-[color-mix(in oklch,var(--secondary),var(--foreground) 5%)]

Literal

literal6 expressions
PreviewExpressionUsed by
bg-[oklch(from var(--primary) 0.3 calc(c*0.4) h)]
Relative-oklch tint derived from --primary.
bg-[oklch(from var(--primary) 0.35 calc(c*0.5) h)]
Relative-oklch tint derived from --primary.
bg-[oklch(from var(--primary) 0.88 calc(c*0.5) h)]
Relative-oklch tint derived from --primary.
bg-[oklch(from var(--primary) 0.93 calc(c*0.4) h)]
Relative-oklch tint derived from --primary.
bg-black/10
bg-white