Deft
Ask AI

Search

Search skills, authors and topics

migrate-radix-to-base

Migrate React projects and shadcn components from Radix UI to Base UI, handling route objects, consumer props, and progressive wrapper migration.

Install

npx skills add https://github.com/shadcn-ui/ui --skill migrate-radix-to-base

Consumer-side prop changes (call sites, not wrappers)

The shadcn wrapper NAMES survive a radix -> base-ui migration, but these props change or disappear at CALL SITES in app code. Sweep every consumer for this list after migrating the wrappers. All entries verified against @base-ui/react@1.6.0 type definitions during real migrations; when in doubt, check node_modules/@base-ui/react/**/*.d.ts, never guess.

Universal

RadixBase UICall-site action
asChild (any wrapper)render prop<Trigger asChild><Button/></Trigger> -> <Trigger render={<Button/>}>...

Per component

ComponentRadix propBase UI fateCall-site action
Accordiontype="single"|"multiple" + collapsibledropped; value/defaultValue are ALWAYS arrays; multiple-open via multipletype="single" collapsible -> remove both; wrap values in arrays; type="multiple" -> multiple
TabsactivationMode="manual"dropped; Base UI defaults to MANUAL activationremove prop; near-equivalent opt-in is Tabs.List activateOnFocus (behavior delta: flag, do not auto-add)
Selectposition="popper"|"item-aligned"alignItemWithTrigger boolean (on Positioner; wrappers expose it)position="popper" -> alignItemWithTrigger={false}; item-aligned -> alignItemWithTrigger (default)
TooltipProviderdelayDuration, skipDelayDurationdelay; skip-delay concept droppedrename / remove
TooltipdisableHoverableContentNO equivalentremove; FLAG the behavior change in the report
Avatar.ImagedelayMsdelayrename
ScrollAreatype="always"|"scroll"|...droppedremove
Separatordecorativedroppedremove
Checkboxchecked="indeterminate"indeterminate is a SEPARATE boolean propchecked="indeterminate" -> indeterminate + boolean checked
SlideronValueChange(value)signature gains event details; also inverted REMOVEDcheck handler arity; remove inverted (flag vertical-inverted usage)
SelectonValueChange(value: string)widens to (value: Value | null, eventDetails)useState<string> + onValueChange={setState} breaks: widen state to string | null or wrap the setter
SlideronValueCommitonValueCommittedrename
ToggleGrouptype="single"|"multiple"multiple boolean; value shape arrayssame treatment as Accordion
ToggleGroup / ToolbarrovingFocus={false}dropped (roving focus always on); loop -> loopFocusremove / rename
Menubarvalue/onValueChange (active menu)dropped; control per Menu.Root openrestructure if used; usually unused
MenubarlooploopFocusrename
ContextMenu.RootmodalREMOVEDremove
ContextMenu.TriggerdisabledREMOVEDremove; gate the trigger yourself
DropdownMenu/ContextMenu items(Radix closed menu on select)closeOnClick defaults FALSE on CheckboxItem/RadioItembehavior delta: flag; add closeOnClick only if the user asks
NavigationMenudelayDuration(200), skipDelayDuration, viewportdelay(50) + closeDelay; viewport prop gone (Positioner handles it)rename/remove; flag the 200->50 hover-delay feel change
Popover / HoverCardopenDelay/closeDelay on Rootmove to TRIGGER as delay/closeDelayrelocate props Root -> Trigger
Dialog / AlertDialogonOpenAutoFocusinitialFocus (element/ref-based, not event-based)restructure: pass target instead of preventDefault handler
Dialog / AlertDialogonCloseAutoFocusfinalFocussame restructure
Dialog familyonEscapeKeyDown, onPointerDownOutside, onInteractOutsideconsolidated; see the overlays reference for exact per-part signaturesconsult overlays.md; do not guess
DirectionProviderdirdirectionrename

Callback signature rule

Base UI callbacks commonly gain an event-details argument: onOpenChange(open, eventDetails), onValueChange(value, eventDetails). Passing an existing single-arg handler stays type-safe; handlers that USED Radix's event parameter need review against the family reference file.

Sweep procedure

  1. grep app code (outside components/ui) for each LHS token above plus asChild.
  2. Fix call sites file by file; typecheck after each file.
  3. Anything on this list marked FLAG goes into the migration report as a behavior delta, never silently patched.