Patina

Command Palette

Search for a command to run...

Sign inGet Pro
Docs

Install Patina

156 free components via the public @patina registry. Add components.json, run the CLI, restyle with CSS variables.

1

Add the registry

Add @patina to components.json:

json
{
  "registries": {
    "@patina": "https://patina-ui.nstranquist.workers.dev/r/{name}.json"
  }
}

If you do not have a components.json file yet, run npx shadcn@latest init first.

2

Install a free primitive

Use the shadcn CLI. Start with marquee — it is never locked:

bash
npx shadcn@latest add @patina/marquee
bash
npx shadcn@latest add @patina/shimmer-button
bash
npx shadcn@latest add @patina/pulse-button
bash
npx shadcn@latest add @patina/rainbow-button
bash
npx shadcn@latest add @patina/magnetic-button
bash
npx shadcn@latest add @patina/button

All 156 free components are on /browse.

CLI usage

Patina is a namespaced shadcn registry. The CLI reads components.json, fetches /r/{name}.json, and copies source into your app.

Init a shadcn project

bash
npx shadcn@latest init

Add a free component

bash
npx shadcn@latest add @patina/marquee

Namespaces

@patina is public.@patina-pro needs a license header — see Pro recipes below.

Cursor MCP

Add Patina to the shadcn MCP server so Cursor can search and install components.

bash
npx shadcn@latest mcp init

The shadcn MCP server uses the registries in components.json. Keep @patina listed there.

Tokens & theming

Patina uses shadcn CSS variables. Restyle by changing the variables — do not hardcode hex. Light and dark share names; .dark remaps values. Live accent / radius / font / density is the customizer on /theme, not a second generator. Form kit: /forms.

Core tokens

  • --background — page background
  • --foreground — primary text
  • --card / --card-foreground — surfaces
  • --primary / --primary-foreground — brand
  • --muted / --muted-foreground — secondary text
  • --border / --input / --ring
  • --brass / --brass-foreground — optional accent
  • --radius — corner scale

Restyle

Edit :root and .dark in globals.css:

css
:root {
  --primary: oklch(0.45 0.12 264);
  --radius: 0.75rem;
}

.dark {
  --primary: oklch(0.75 0.08 264);
}

Light / dark

Toggle the .dark class on <html>. next-themes is the usual switch:

tsx
<ThemeProvider attribute="class" defaultTheme="dark">
  {children}
</ThemeProvider>

Reduced motion

Animated primitives read prefers-reduced-motion. Marquee becomes a static row. Dock stops magnifying.

css
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}
Pro recipes

Private registry

PATINA_LICENSE_KEY, @patina-pro add, and zip download stay with Pro. Free primitives above do not need a key.

Ready to explore?

Browse the catalog or open a live template.