Install any Proper UI component with the shadcn CLI — configure the @properui namespace once and run npx shadcn@latest add @properui/<name>.
Every Proper UI entry is also published in shadcn's registry format under a @properui namespace, alongside our own CLI and /r registry. Once the namespace is configured, npx shadcn@latest add @properui/<name> copies source into your project exactly like npx @properui/cli@latest add <name> does — same files, same dependency resolution — through a tool you may already have wired into your project or editor. It also means shadcn's own MCP server and Skill can discover and install Proper UI components without any extra setup on your end.
Configure the namespace
Add @properui to the registries field of your project's components.json:
// components.json
{
"registries": {
"@properui": "https://properui.dev/r/shadcn/{name}.json"
}
}
Don't have a components.json yet? npx shadcn@latest init creates one; see components.json for what the other fields mean. Once the namespace is set:
npx shadcn@latest add @properui/buttons
resolves to https://properui.dev/r/shadcn/buttons.json, installs react-aria-components and any other npm dependencies it needs, and writes files under whatever aliases.ui / aliases.lib / aliases.hooks point to in your components.json — the same alias-driven placement shadcn uses for its own components, so the files land next to the rest of your project's UI rather than mirroring Proper UI's internal components/base/... layout.
What's discoverable
https://properui.dev/r/shadcn/registry.json is the index shadcn's CLI and MCP server read to see the whole catalog — every base component, application component, marketing section, page example, hook, and util Proper UI ships, mapped to shadcn's vocabulary:
| Proper UI (native) | shadcn type | Example |
|---|---|---|
component | registry:ui | buttons, avatars |
example (page) | registry:block | about-page-01, dashboard-01 |
hook | registry:hook | use-breakpoint |
util | registry:lib | cx, countries |
style | registry:style | styles (theme tokens + CSS) |
Internal references translate too: a native registryDependencies entry like "tooltip" becomes "@properui/tooltip", so the CLI resolves transitive dependencies inside the @properui namespace automatically — installing about-page-01 pulls in every section it's built from (headers, footers, careers cards, and so on) the same way npx @properui/cli@latest add about-page-01 would.
The @properui/icons dependency
Proper UI's icon set is @properui/icons, an npm alias for @untitledui/icons ("@properui/icons": "npm:@untitledui/icons@^0.0.22" in packages/ui/package.json). Components that use icons declare that exact alias spec in their shadcn dependencies array — e.g. "@properui/icons@npm:@untitledui/icons@^0.0.22" — rather than the bare package name.
This isn't a guess: it was verified against a real npx shadcn@latest add @properui/buttons run against a locally-served copy of this registry. The CLI passed the alias spec straight through to the installed package.json:
"dependencies": {
"@properui/icons": "npm:@untitledui/icons@^0.0.22"
}
which is exactly what you'd get running npm install or pnpm add with that spec by hand — shadcn doesn't parse or validate the string, it just hands it to your package manager.
Limits
- Styles have no good target. shadcn's
targetplaceholders cover@components/,@ui/,@lib/, and@hooks/— there's no equivalent for global CSS. Thestylesitem (registry:style, theme tokens +globals.css+typography.css) installs, but without an explicit target it falls back to yourcomponentsalias directory (e.g.src/components/globals.css), which is almost never where you want theme CSS. Usenpx @properui/cli@latest initfor the initial theme setup instead, and reach fornpx shadcn@latest add @properui/stylesonly if you're comfortable moving the files afterward. type: "registry:style"here isn't a shadcn base style. shadcn's ownregistry:styleitems (likenew-york) are style presets — they can extendcssVars/css/tailwindconfig directly. Proper UI'sstylesentry is a files-only translation of our nativestyletype; it doesn't participate in shadcn's style-extension mechanism.registry.jsonis a catalog, not a payload. Item summaries there omitfiles(no inline source) by design, matching how shadcn's own rootregistry.jsonis structured and what its MCP server expects to read for discovery. Fetch the individual@properui/<name>.jsonitem for file content.- The native registry is still the source of truth. Fields like
layer,examples(the demo-preview ids used on component docs pages), and per-file granularity beyond shadcn's fiveregistry:*types don't have a shadcn equivalent and are dropped, aside fromlayersurviving asmeta.layerfor reference. If you're scripting against Proper UI rather than using shadcn's CLI, prefer/r/<name>.json(see components.json) — it's the format our own CLI and docs site are built on.