loading-ui is distributed as a custom shadcn registry. The intended flow is:
@loading-ui registry to components.json.Before installing from this registry, your project should already have:
components.json file for the shadcn CLIIf you do not have components.json yet, initialize shadcn first:
pnpm dlx shadcn@latest init
Add @loading-ui to the registries section of your components.json:
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "base-nova",
"tailwind": {
"css": "app/global.css",
"baseColor": "neutral",
"cssVariables": true
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {
"@loading-ui": "https://loading-ui.com/r/{name}.json"
}
}Once that is in place, the CLI can resolve items like @loading-ui/ring.
Use the shadcn CLI to pull a component into your project:
pnpm dlx shadcn add @loading-ui/ring
You can swap ring for any registry item you want to try:
@loading-ui/ring@loading-ui/spokes@loading-ui/classic@loading-ui/analyzing-imageThe installed files are yours. Edit names, classes, motion timing, and import paths to match your app.
Keep loading indicators close to the action they describe. A good default is to pair motion with enough layout context that users can tell what is currently happening.
import { Ring } from "@/components/loading-ui/ring";
export function SaveButton({ isSaving }: { isSaving: boolean }) {
return (
<button
type="button"
disabled={isSaving}
className="inline-flex items-center gap-2 rounded-md border px-3 py-2"
>
{isSaving ? <Ring className="size-4" /> : null}
<span>{isSaving ? "Saving..." : "Save changes"}</span>
</button>
);
}If you do not want to use the registry flow, you can still copy component source directly from the docs and adapt it manually. That works well when your project structure differs from the default shadcn conventions or when you want tighter control over naming and placement.
Browse Components when you want a specific primitive, or read Philosophy to understand the design constraints behind the library.