shadcn/ui
What it is: A radically different distribution model for UI components. Not a package — a CLI that copies component source code into your repo, where you own and modify it.
Status: Massively popular among modern React/Tailwind projects since ~2023. Solo-author (shadcn / Brian Lovin et al) origin, now community-extended.
Most relevant to Locara: A novel distribution pattern that fits Locara’s “apps are owned by the developer” ethos. Worth considering for @locara/components.
Background
shadcn/ui inverted the conventional component-library paradigm. Instead of npm install @shadcn/ui and importing components, you run npx shadcn add button and the source code for Button is copied into your project under components/ui/button.tsx. You own it. You modify it. You upgrade by re-running the command and merging.
This solves the fundamental tension between “I want a polished component library” and “I need to customize a thousand small things to match my design system” without resorting to wrapping or CSS-overriding.
Key design decisions
- Components copied as source code, not installed as deps. No
node_modules/@shadcn, just files in your repo. - CLI-driven (
shadcnCLI) for adding, listing, updating components. - Tailwind + Radix primitives under the hood. Components leverage Radix for accessibility/behavior; Tailwind for styling.
- Schema-based registry. Components defined in a structured way, distributable across frameworks.
- No versioning of components per-project — once copied, they’re yours; updates are diffs you choose to apply.
- MIT licensed. Permissive.
- Extended ecosystem of registries — third-party “shadcn-style” component sets exist (e.g., aceternity, magicui, motion-primitives) using the same distribution model.
What worked
- Customization-first DX. Need to change
Button’s padding for your design system? Just edit the file. No props proliferation, no theme override systems. - Zero dep bloat. You bundle only what you use, no surprise transitive dependencies.
- AI-friendly. LLMs can read, modify, and generate shadcn components — they look like ordinary React code in your repo. This is increasingly important.
- Drove Tailwind/Radix adoption. Network effect — became the de facto modern React component default.
- The model is reusable. Shadcn proved the distribution-as-CLI pattern; others adapted it.
- No semver hell. No “we updated
Buttonand now your tooltip is broken” because you control the version of every component.
What failed / criticisms
- Maintenance burden shifts to the user. Bug fixes upstream require manual re-add.
- Diffing local edits with upstream updates is awkward. No good tool for “merge my mods with the new version.”
- Doesn’t work for headless components that need centralized state. The pattern is for visual primitives; complex stateful components don’t fit.
- Ecosystem overlap is messy — multiple registries with their own variations of the same components.
- Tailwind dependency is non-negotiable. If you don’t want Tailwind, you can’t use it.
- No type-level guarantees across versions. Components in different projects drift; reusable patterns hard to share back upstream.
Specific learnings for Locara
- shadcn-style distribution is genuinely interesting for Locara’s component library. Imagine
npx locara add chatcopiesChat.tsxinto a Locara app’s source. The author owns it, can customize freely, ship a polished UX without fighting a black-box library. Strongly worth considering for@locara/componentsover a traditional npm package. - AI authoring becomes much easier. LLMs can read and modify Locara components in the repo. Authoring flow: “Claude, change the chat input to support voice” → it edits the file. Possible because the source is local. Aligns perfectly with your “agent-friendly” goal.
- Registry as schema, not just code. shadcn defines components in a structured
registry.jsonwith metadata. Locara’s components could publish similarly — a registry of “primitives” from which apps pick what they need. - Multiple registries are a feature. Locara could have an official component registry plus community-contributed ones. App devs
locara add chat --from=acme-design-systemto use a different visual style. - Caveat — review implications. If components are copied into the app, every app’s component code is in scope for security review. shadcn-style + Locara automated review = each copy is auditable but creates duplication. Tradeoff worth thinking through.
- Don’t use this pattern for the Locara core SDK. Core APIs (
llm.chat,db.query, etc.) are imports from@locara/sdk— versioned, semver, stable contract. shadcn-style is for the UI layer where customization is the value, not for the runtime where stability is the value. - Hybrid is fine.
@locara/sdkas a normal package;@locara/componentsas a shadcn-style copy-in registry. Different contracts for different concerns.
References
- https://ui.shadcn.com/
- https://ui.shadcn.com/docs
- https://github.com/shadcn-ui/ui
- “Why I built shadcn/ui” blog posts