跪拜 Guibai
← All articles
Frontend

shadcn/ui Switched Defaults to Base UI — Radix Isn't Dead, but the Old Assumption Is

By 不辞远_Web3 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Any team using shadcn/ui with AI coding tools now risks silent breakage: LLMs trained on mixed-era code will blend Base UI and Radix APIs, producing type errors and broken state styles. Specifying the backend in PRDs and prompts prevents that, and the default shift signals which library will get faster component coverage going forward.

Summary

Starting July 2026, shadcn/ui initializes new projects with Base UI as the underlying component library. The change follows months of coexistence where community adoption tilted 2:1 toward Base UI, which now clocks over 6 million weekly downloads. Radix is not deprecated — existing projects stay untouched, and a `-b radix` flag preserves the old path for new work.

The shift reflects component coverage more than quality. Radix's Dialog, Popover, and Select are mature, but Base UI ships faster with Combobox, Autocomplete, Number Field, Drawer, and OTP Field — the controls modern SaaS and AI products actually need. API differences like `render` vs. `asChild` and `data-open` vs. `data-[state=open]` are real but only surface when customizing component internals.

What changed most is shadcn/ui's identity. It now distributes the same component names, CLI, Registry, and Blocks across Base UI, Radix, and React Aria backends, stabilizing its own distribution system rather than any single primitive library. For AI-assisted coding, this means prompts must explicitly name the backend to prevent mixing incompatible APIs.

Takeaways
New shadcn/ui projects default to Base UI; Radix remains fully supported and existing projects are not auto-migrated.
Initialize with `pnpm dlx shadcn init -b radix` to keep using Radix on a new project.
Community adoption already favored Base UI roughly 2:1 before the default changed, and Base UI passed 6 million weekly downloads.
Base UI covers modern controls like Combobox, Autocomplete, Number Field, Drawer, and OTP Field faster than Radix.
Radix uses `asChild` and `data-[state=open]`; Base UI uses `render` and `data-open`. The differences matter when customizing component internals.
shadcn/ui now distributes the same component surface across Base UI, Radix, and React Aria — it is a distribution system, not a Radix wrapper.
AI coding tools frequently mix Base UI and Radix APIs; prompts and PRDs should explicitly name the backend to avoid broken code.
Conclusions

shadcn/ui's pivot reveals that component-library competition is shifting from stability of classic primitives to speed of coverage for modern application controls like comboboxes and OTP fields.

The real lock-in with shadcn/ui was never the npm dependency but the copied source code in `components/ui` that teams customize — making a backend migration far more expensive than a package swap.

By decoupling its CLI, Registry, and Blocks from any single primitive library, shadcn/ui is positioning itself as a component-distribution platform, which insulates it from the fate of any one backend.

AI code generation introduces a new constraint on framework defaults: every backend split creates a surface for LLMs to hallucinate incompatible API mixtures, forcing teams to encode backend choices into prompts.

Concepts & terms
asChild
A Radix UI pattern where a parent component delegates its trigger behavior to its child element instead of rendering an extra wrapper, e.g., `<DialogTrigger asChild><Button /></DialogTrigger>`.
render prop (Base UI)
Base UI's composition mechanism where the element to render is passed directly as a prop, optionally as a function receiving component state, e.g., `render={<Button />}` or `className={(state) => state.checked ? '...' : '...'}`.
shadcn/ui Registry
A component distribution system that lets developers install pre-built components from a remote source into their local project, decoupled from any single underlying primitive library.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗