/

Radix, Base UI and shadcn: Which Layer You Are Choosing

They are not alternatives, they are three layers of one stack. What each gives you, what copied source really costs, and where packaged libraries still win.

Serafim Korablev
Serafim Korablev
@korablev

"Radix or shadcn" is a question with a category error in it. They are not alternatives, they are two layers of the same stack: shadcn/ui is a set of components built on Radix primitives, distributed as source you copy rather than as a package you install. Base UI is the newer primitive layer from the same lineage. Choosing between them is really choosing how much you want to own.

The three layers

Primitives. Radix and Base UI. These give you behaviour with no styling: focus management, portals, collision-aware positioning, keyboard handling, ARIA wiring, controlled and uncontrolled state. A dialog that traps focus and returns it, a select with typeahead, a tooltip that does not open on touch. No opinion about how any of it looks.

Composed components. shadcn/ui. Those primitives with Tailwind classes, variants and sensible defaults, delivered by a CLI that copies the source into your repository. There is no dependency to bump, because the code is yours the moment you run add.

Registries. Everything built on top and distributed the same way: the animated sets, the general product sets, the single-purpose ones. The registry landscape guide sorts them.

Nearly every "which should I use" question resolves once you notice you are usually using two of these at once.

When the primitive layer is the right choice

Reach for Radix or Base UI directly when you have a design system with its own tokens and components, and adopting someone else's class names would mean fighting them. You get the hard part - the behaviour - and write every pixel yourself.

That is a real cost. The keyboard and screen reader contracts for a menu, a combobox and a dialog are the parts that take the longest to get right, and they are exactly what the primitive gives you. What it does not give you is a single line of visual design.

Radix or Base UI

Radix is the established layer: widely used, stable, and what shadcn/ui is built on today. Base UI is the newer effort from overlapping authors, with a cleaner API and a more consistent styling story.

The practical answer for most teams is that this is not a decision you make in isolation. If you are using shadcn/ui, you get whichever layer it ships on. If you are building a design system from scratch and starting today, Base UI is worth evaluating properly rather than defaulting to what your last project used.

What shadcn/ui actually is

Worth stating plainly, because it is the source of most of the confusion: it is not a component library in the npm sense. There is no shadcn/ui package in your dependencies. The CLI fetches source files and writes them into components/ui, and from that moment they are your files.

The consequences are the whole trade. You can change anything, with no wrapper and no fighting a prop API. Upstream fixes do not arrive on their own. Two registries can overwrite each other's button.tsx. And your components do not have a version, which is either freedom or a governance problem depending on the size of the team.

MUI, Chakra and the packaged libraries

The other side of the split. A packaged library gives you a versioned dependency, a documented prop API and a theme system, and takes back the ability to change anything the API does not expose. That is a reasonable trade for a large team that wants consistency enforced, and an unreasonable one for a product whose design is a differentiator.

The migration people ask about most - a packaged library to shadcn - is a rewrite of the visual layer, not a swap. The behaviour maps cleanly; the theming does not.

Where else to look

The honest list, because the answer is not always us:

SourceBest forTrade-off
Radix PrimitivesBehaviour for a design system you ownNo styling at all
Base UIThe same idea with a newer APIYounger, with a smaller ecosystem around it
shadcn/uiThose primitives, styled, as source in your repoNo upstream fixes, no version
React AriaThe most thorough internationalisation and screen reader workThe largest API surface of the three
21stComponents built on all of the above, with live previewsQuality varies by author, so preview before you take it

Taking one

Every component page has a live preview and the code. Installing goes through the shadcn CLI against our registry:

bash

That key comes from your 21st account, and installs require a membership. Set API_KEY_21ST once in your shell and the command works for anything in the catalogue. The 21st MCP covers the same ground without leaving the editor: ask Claude, Cursor or Codex for a component, get the previews inline, and let the agent write the file.

Browse the registry directory →

Frequently asked

Is shadcn/ui a component library?
Not in the npm sense. There is no package in your dependencies: the CLI fetches source files and writes them into your repository, and from that moment they are your files. That is why there is nothing to upgrade, why upstream fixes do not arrive on their own, and why two registries can overwrite each other's button.
Should I use Radix or Base UI?
Radix is the established layer and what shadcn/ui builds on today; Base UI is the newer effort from overlapping authors with a cleaner API. If you are already using shadcn/ui you get whichever it ships on. If you are starting a design system from scratch today, Base UI is worth evaluating properly rather than defaulting to your last project's choice.
When should I use primitives directly instead of shadcn?
When you have a design system with its own tokens and adopting someone else's class names would mean fighting them. Primitives give you the hard part, which is the keyboard, focus and screen reader behaviour for menus, comboboxes and dialogs, and no visual design whatsoever.
How hard is migrating from MUI or Chakra to shadcn?
The behaviour maps almost one to one; the theming does not. A theme object does not translate into CSS variables and utility classes without decisions, so treat it as a rewrite of the visual layer rather than a swap, and expect the theme to be most of the work.

Published

Aug 20, 2026

Read time

5 min

Tags

ComparisonPrimitivesReactDesign systems

Share