1. Add the registry#
Add the @pixilui namespace to components.json, once per app:
{
"registries": {
"@pixilui": "https://pixilui.com/r/{name}.json"
}
}The URL is the site's own address followed by /r/{name}.json. The item pages show the exact line for the site you are on.
2. Install an item#
npx shadcn@latest add @pixilui/approval-cardThe CLI:
- copies the item and every item it depends on into
components/pixilui/(for the approval card:button.tsx,input.tsx,approval-card.tsx); - copies the foundation:
foundation.css,motion-tokens.tsandlib/(utils.ts,use-measure.ts,use-morph-size.ts); - installs
motion,clsxandtailwind-merge; - adds the foundation import to your global stylesheet.
Installed files import each other with relative paths (./button, ./lib/utils), so they work whatever your import alias is.
Without the namespace, you can install from the full URL. Dependencies are listed as full URLs in the registry, so they resolve too:
npx shadcn@latest add https://pixilui.com/r/approval-card.json3. The foundation import#
Every item reads the tokens in foundation.css. The CLI adds the import for you. If your global stylesheet does not have it, add it after Tailwind:
@import "tailwindcss";
@import "../components/pixilui/foundation.css";The path is relative to the stylesheet. In a Next.js app with app/globals.css it is ../components/pixilui/foundation.css; in a Vite app with src/index.css and components in src/components, it is ./components/pixilui/foundation.css.
foundation.css styles nothing by itself: it defines custom properties and Tailwind utilities, and adds no rules to body. Installing it never restyles your page.
Next.js#
Use the App Router with Tailwind v4. Items that hold state start with "use client", so you can render them from server components.
Load the fonts with next/font and put the variables on <html>. The tokens look for --font-geist-sans (display), --font-inter (body) and --font-geist-mono (numbers and code), then fall back to the family names and the system fonts.
import { Geist, Geist_Mono, Inter } from "next/font/google";
const geist = Geist({ variable: "--font-geist-sans", subsets: ["latin"] });
const geistMono = Geist_Mono({ variable: "--font-geist-mono", subsets: ["latin"] });
const inter = Inter({ variable: "--font-inter", subsets: ["latin"] });
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={`${geist.variable} ${geistMono.variable} ${inter.variable}`}>
<body>{children}</body>
</html>
);
}Then import and render:
import { ApprovalCard } from "@/components/pixilui/approval-card";Vite#
Create the app with the React and TypeScript template, add Tailwind v4 with @tailwindcss/vite, set the @/* path alias in tsconfig.json and vite.config.ts, and run npx shadcn@latest init. The shadcn CLI writes components.json with src/components as the target, so items land in src/components/pixilui/.
Fonts: load Geist, Inter and Geist Mono however you prefer (Fontsource, a <link> to Google Fonts, or self-hosted files) and set the variables on :root:
:root {
--font-geist-sans: "Geist";
--font-inter: "Inter";
--font-geist-mono: "Geist Mono";
}Manual copy#
Every item page has a Manual tab that lists each file with its full source and its target path. To install by hand:
- Copy the foundation files from the Foundation page into
components/pixilui/. - Copy the item's files, and the files of any item it depends on, to the paths shown.
- Install the npm packages listed on the page.
- Add the
foundation.cssimport to your global stylesheet.
Keep the file names and folders as shown: the files import each other relatively.
Updating#
Run the same add command again. The CLI asks before overwriting a file you changed. Items are source you own, so review the diff the way you would review any other change.