Installation

liquidcn installs through the shadcn CLI, into a project that already uses shadcn/ui.

Requirements

  • React 19. The wrappers take ref as a prop.
  • Tailwind CSS v4, which the shadcn base components are written for.
  • A components.json. In a new project, create one with:
pnpm dlx shadcn@latest init

Add a component

Every component has its own registry item. Pick one from Components, or start with the button:

pnpm dlx shadcn@latest add https://liquidcn.snmandela.com/r/liquid-button.json

An item brings the liquid component, the shadcn component it extends, liquid.css, and the motion modules it needs. Installing a second component reuses the shared files.

Use a namespace

To skip the full address, register liquidcn in components.json:

components.json
{
  "registries": {
    "@liquidcn": "https://liquidcn.snmandela.com/r/{name}.json"
  }
}
pnpm dlx shadcn@latest add @liquidcn/liquid-button

What lands where

Files keep their folders, so every @/components/ui/… and @/lib/… import resolves. For the button:

components/
  ui/
    button.tsx        the shadcn component, unchanged
    liquid/
      button.tsx      the wrapper you import
      liquid.css      glass, keyframes, accessibility preferences
lib/
  liquid/
    motion.ts         the spring and shared helpers
    press.ts          swell, stretch, and content morph

The shadcn component stays where it was, and other code that imports it is unaffected.

Mount the Toaster

Toasts need one Toaster near the root of your app. Other components need no setup.

app/layout.tsx
import { Toaster } from "@/components/ui/liquid/sonner"

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Toaster />
      </body>
    </html>
  )
}

Server components

Every wrapper starts with "use client", so you can render them from server components as usual. Each one imports liquid.css itself; there is nothing to add to your global stylesheet.