UI Libraries
FivUI components can be built on either Radix UI or Base UI. This page explains the difference, how to choose, and how to switch.
Radix UI vs Base UI
| Aspect | Radix UI | Base UI |
|---|---|---|
| Origin | Modulz / WorkOS — established, widely used in the React ecosystem | MUI team — modern, headless primitives with strong accessibility |
| Composition | asChild + Slot for polymorphic components | render prop and compound components |
| Styling | Unstyled; data-* attributes for state | Unstyled; similar data-* patterns, some different names |
| Floating UI | Built-in positioning (Popover, Tooltip, Select, etc.) | Uses Positioner subcomponents for popovers/tooltips/selects |
| Bundle / ecosystem | Per-component packages (e.g. @radix-ui/react-dialog) | Single @base-ui/react or per-primitive imports |
FivUI keeps the same public API (component names, props, refs) for both backends, so your app code does not change when you switch libraries — only the underlying primitives and the CLI template used at install time.
Choosing a library
- Radix UI: Default in FivUI. Best if you want the most widely adopted headless primitives, maximum community examples, and consistency with many existing shadcn/Radix-based projects.
- Base UI: Good if you prefer the MUI ecosystem, want a single vendor for primitives, or are building a design system that aligns with Base UI's API style (e.g.
renderprops).
You choose once during fivui init (or set uiLibrary in fivui.json), and can override per component with --radix or --base when running fivui add.
Switching between libraries
To switch a project from Radix to Base UI (or the other way around), you change which template is used for each component. Your React code (imports from @/components/ui/...) stays the same.
Option 1: Re-add components with the desired flag
Remove the component file(s) for the primitive you want to switch, then re-add with the target library. Example for dialog:
# Remove existing dialog component files, then:npx fivui add dialog --base # or --radix to switch to RadixRepeat for each component you want to switch. Dependencies in package.json will be updated when you run install.
Option 2: Change default and add new components only
Set uiLibrary in fivui.json to "base" (or "radix"). New components you add with fivui add <name> will use that library. Existing components are unchanged until you re-add them as in Option 1.
Compatibility notes
- Aspect Ratio: FivUI uses pure CSS for the aspect-ratio component; there is no Base UI equivalent. The same implementation is used regardless of
uiLibrary. - AppKits: Email and Kanban AppKits do not depend on a primitive library directly. They use FivUI components (Dialog, ScrollArea, etc.). Those sub-components are installed with whatever library you chose when adding the AppKit (
--radix,--base, or config default). - Mixed usage: You can have some components from Radix and others from Base UI in the same project by using
--radixor--baseperfivui add. Ensure you have both dependency sets installed if you mix.
FAQ
Do I need to change my React code when switching?
No. FivUI exports the same component names and props from both Radix and Base UI templates. You only change how the component is installed (which template and which primitive dependencies are added).
What if a component doesn’t support Base UI?
A few components (e.g. Aspect Ratio) have no Base UI counterpart and use a shared implementation. For those, the registry does not define a base variant; the CLI will use the single available template regardless of uiLibrary.
Where is the library choice stored?
In fivui.json in your project root: "uiLibrary": "radix" or "uiLibrary": "base". If omitted, the CLI defaults to radix. You can override per command with --radix or --base.
See also: Installation (Step 2: UI primitive library) and CLI (add and init options).