shadcn/ui is a component collection for React that is not a component library — a distinction its creator emphasises and its users ignore. Traditional component libraries (Material UI, Chakra UI, Ant Design) are npm packages: install them, import them, use them, and inherit their opinions, their bugs, and their major version upgrades. shadcn/ui is different: instead of installing a package, the developer copies component source code directly into their project. The code is theirs. The maintenance is theirs. The 200 lines of React, Tailwind CSS, and Radix primitives that constitute a <DataTable> are now the developer’s problem.
This is either brilliant or terrifying, depending on whether the developer reads the code they copy.
shadcn/ui was created in 2023 and achieved immediate cultural dominance through a combination of excellent design, a novel distribution model, and the enthusiastic endorsement of every AI coding assistant on the planet — each of which, when asked “how should I build a UI?”, responds with shadcn/ui before the question mark has rendered.
The AI’s Default Answer
shadcn/ui’s most remarkable characteristic is not its technology but its position in the training data.
Every major language model — Claude, GPT, Gemini, Copilot — has been trained on documentation, tutorials, and blog posts from 2023–2025, a period during which shadcn/ui was the most discussed, most documented, and most recommended component collection in the React ecosystem. The result is a self-reinforcing loop:
- AI models recommend shadcn/ui
- Developers adopt shadcn/ui because AI recommended it
- Developers write blog posts about shadcn/ui
- AI models are trained on the blog posts
- AI models recommend shadcn/ui with even greater confidence
This loop has produced a phenomenon in which a developer who asks an AI assistant to build a form receives a shadcn/ui form — not because shadcn/ui is the best tool for the job (it may or may not be), but because shadcn/ui is the most available answer in the model’s training data. The AI does not evaluate alternatives. The AI pattern-matches. The pattern is shadcn/ui.
“FRONT-END! React! Next.js! A design system! Tailwind! Shadcn! A component library with—”
“I like templ. It makes for reliable fast pages.”
— The Caffeinated Squirrel and riclib, The Front Door, or The Night the Palace Finally Faced the Street
The Squirrel proposes shadcn/ui. The Squirrel always proposes shadcn/ui. The Squirrel has excellent taste in components and no instinct for architectural restraint. This is the Squirrel’s nature.
The Stack Tax
shadcn/ui does not exist alone. shadcn/ui exists inside a stack:
- React — the rendering library (mandatory)
- Tailwind CSS — the styling framework (mandatory)
- Radix UI — the accessibility primitives (mandatory)
- class-variance-authority — the variant utility (recommended)
- clsx / tailwind-merge — the class name utilities (recommended)
- TypeScript — the type system (assumed)
To use a shadcn/ui button, the developer needs React, Tailwind, Radix, a bundler, a TypeScript compiler, and a tailwind.config.js. This is not a button. This is an ecosystem. The button is the visible tip; the ecosystem is the iceberg beneath.
The lifelog blog has a button. The button is:
<button>Submit</button>
Styled by 651 lines of CSS in a Go function. No React. No Tailwind. No Radix. No bundler. No TypeScript compiler. No tailwind.config.js. The button works. The button has always worked. HTML buttons have worked since 1993.
The Copy-Paste Paradox
shadcn/ui’s distribution model — copy code into your project rather than install a dependency — solves the dependency hell problem. The developer is no longer subject to breaking changes in upstream packages, because there is no upstream. The code is local. The code is owned.
But ownership has a cost. When Radix releases a fix for an accessibility bug, every npm-based component library gets the fix automatically. shadcn/ui users must re-copy the component, diff it against their modifications, merge the changes, and test. This is, in effect, vendor management — the same activity that enterprise software teams perform with commercial dependencies, now performed by individual developers with open-source components they copied from a website.
The paradox: shadcn/ui frees the developer from dependency management by making them the dependency manager.
The War Wounds
riclib’s encounter with shadcn/ui is part of a longer campaign across the CSS framework landscape — Pico CSS, Bulma, DaisyUI, Tailwind CSS, shadcn/ui — each battle fought, each battle lost. The wounds are documented not in code (the code was removed) but in the conclusion: no more frameworks.
The progression tells a story:
- Pico CSS: tried to avoid CSS entirely → ended in a straight jacket of inline overrides
- Bulma: component framework with grid opinions → opinions became constraints
- DaisyUI: Tailwind with pre-built components → debugging two layers of abstraction
- Tailwind: utility-first, maximum flexibility → unreadable HTML, vocabulary tax
- shadcn/ui: copy-paste components, “own the code” → owning 200 lines of someone else’s React per component
Each framework promised to make CSS easier. Each framework delivered a different kind of difficulty. The conclusion, reached through exhaustion rather than theory: write your own CSS. Per project. No framework. No opinions to override. No vocabulary to memorise. No components to own. Just CSS, written by someone who finally learned it because every alternative proved more expensive.
The lifelog blog has 651 lines of CSS. The V4 product has 13,000 across 34 files — its own custom framework with BEM-inspired naming, tokens.css design system, and go:embed as its build step. Neither uses shadcn. Neither uses Tailwind. Neither uses React. Both were written by a developer who stopped fighting frameworks and started writing CSS.
Measured Characteristics
- shadcn/ui components available: ~40
- npm dependencies per component: 0 (by design)
- Actual dependencies (React, Tailwind, Radix, etc.): 5+ (by necessity)
- Lines of code per typical component: 100–300 (now yours)
- AI models that default to shadcn/ui: all of them
- Blog posts about shadcn/ui in training data: thousands
- Times proposed by the Squirrel: at least 2
- Times adopted in the lifelog: 0
- Times adopted in V4 product: 0 (built own CSS framework)
- CSS frameworks riclib has fought: 5
- CSS frameworks riclib uses now: 0
- The copy-paste paradox: you own the code and the maintenance
- The AI paradox: recommended because recommended
