# Base vs Radix API differences between `base` and `radix`. Check the `base` field from `npx shadcn@latest info`. ## Contents - Composition: asChild vs render - Button / trigger as non-button element - Select (items prop, placeholder, positioning, multiple, object values) - ToggleGroup (type vs multiple) - Slider (scalar vs array) - Accordion (type and defaultValue) --- ## Composition: asChild (radix) vs render (base) Radix uses `asChild` to replace the default element. Base uses `render`. Don't wrap triggers in extra elements. **Incorrect:** ```tsx
``` **Correct (radix):** ```tsx ``` **Correct (base):** ```tsx }>Open ``` This applies to all trigger and close components: `DialogTrigger`, `SheetTrigger`, `AlertDialogTrigger`, `DropdownMenuTrigger`, `PopoverTrigger`, `TooltipTrigger`, `CollapsibleTrigger`, `DialogClose`, `SheetClose`, `NavigationMenuLink`, `BreadcrumbLink`, `SidebarMenuButton`, `Badge`, `Item`. --- ## Button / trigger as non-button element (base only) When `render` changes an element to a non-button (``, ``), add `nativeButton={false}`. **Incorrect (base):** missing `nativeButton={false}`. ```tsx ``` **Correct (base):** ```tsx ``` **Correct (radix):** ```tsx ``` Same for triggers whose `render` is not a `Button`: ```tsx // base. } nativeButton={false}> Pick date ``` --- ## Select **items prop (base only).** Base requires an `items` prop on the root. Radix uses inline JSX only. **Incorrect (base):** ```tsx ``` **Correct (base):** ```tsx const items = [ { label: "Select a fruit", value: null }, { label: "Apple", value: "apple" }, { label: "Banana", value: "banana" }, ] ``` **Correct (radix):** ```tsx ``` **Placeholder.** Base uses a `{ value: null }` item in the items array. Radix uses ``. **Content positioning.** Base uses `alignItemWithTrigger`. Radix uses `position`. ```tsx // base. // radix. ``` --- ## Select — multiple selection and object values (base only) Base supports `multiple`, render-function children on `SelectValue`, and object values with `itemToStringValue`. Radix is single-select with string values only. **Correct (base — multiple selection):** ```tsx ``` **Correct (base — object values):** ```tsx ``` --- ## ToggleGroup Base uses a `multiple` boolean prop. Radix uses `type="single"` or `type="multiple"`. **Incorrect (base):** ```tsx Daily ``` **Correct (base):** ```tsx // Single (no prop needed), defaultValue is always an array. Daily Weekly // Multi-selection. Bold Italic ``` **Correct (radix):** ```tsx // Single, defaultValue is a string. Daily Weekly // Multi-selection. Bold Italic ``` **Controlled single value:** ```tsx // base — wrap/unwrap arrays. const [value, setValue] = React.useState("normal") setValue(v[0])}> // radix — plain string. const [value, setValue] = React.useState("normal") ``` --- ## Slider Base accepts a plain number for a single thumb. Radix always requires an array. **Incorrect (base):** ```tsx ``` **Correct (base):** ```tsx ``` **Correct (radix):** ```tsx ``` Both use arrays for range sliders. Controlled `onValueChange` in base may need a cast: ```tsx // base. const [value, setValue] = React.useState([0.3, 0.7]) setValue(v as number[])} /> // radix. const [value, setValue] = React.useState([0.3, 0.7]) ``` --- ## Accordion Radix requires `type="single"` or `type="multiple"` and supports `collapsible`. `defaultValue` is a string. Base uses no `type` prop, uses `multiple` boolean, and `defaultValue` is always an array. **Incorrect (base):** ```tsx ... ``` **Correct (base):** ```tsx ... // Multi-select. ... ... ``` **Correct (radix):** ```tsx ... ```