src/components/ui/primitives/ radix/ ← Radix implementations base/ ← Base UI implementations
Both folders export the same names with compatible props. When you copy a block component, you only need to install the primitive variant you prefer:
// This import path never changes, regardless of engineimport { Button } from '@/components/ui/button';import { Select, SelectTrigger, SelectContent } from '@/components/ui/select';
Base UI Popover does not expose a standalone Anchor component. The Base UI adapter uses a native <div> with the same data-slot, preserving the public API.
Base UI Tabs includes an optional TabsIndicator component (sliding highlight) that Radix lacks. This is exported as a bonus in the Base UI variant without breaking existing code.
Base UI Select defaults to aligning the selected item with the trigger text. This behavior is controlled by the alignItemWithTrigger prop on Positioner and is enabled automatically when position="item-aligned".
You can mix Radix and Base UI primitives in the same project. There is no runtime engine lock-in — the choice is made per primitive at install time.