← SkillSafe
Base UI Desk

For teams moving a shadcn project off Radix UI

Base UI Deskradix-ui imports, Content, asChild, data-[state=open]. The mechanical changes happen right here; the hand-off items get a review.

Paste one Radix UI file - a shadcn ui wrapper, a page that uses the wrappers, or a hand-rolled composition. Your browser rewrites the mechanical layer: both import forms become one @base-ui/react subpath, Overlay becomes Backdrop, a popover or menu Content becomes Portal > Positioner > Popup with side and align on the Positioner, asChild becomes render, and data-[state=open] becomes data-open. It flags what needs a hand: the animation idiom, dismiss callbacks, the parts Base UI lacks and the behavior changes - and it never touches cmdk, vaul or sonner. Then the review, and the whole file.

Try a sample:

The source file free

The scan free

What the scan found

The skill's migration layers

The Base UI copy free

What the page changed itself - the imports, the part renames, Portal > Positioner > Popup, asChild to render, Part.Props, the data-state classes and --radix variables, and the 1:1 call-site props - saved as <component>-base.tsx next to the original, the way the skill's progressive migration works. Everything that needs a decision is left as it was.

component-base.tsx


    

The review

Pricing as soon as the session is ready...

NOT RUN YET

The page's check of this reply

    Saved reviews

    How it works - and what it cannot see

    The scan reads the JSX itself: comments, strings, template literals and regex literals are masked, every element is matched to its closing tag, and the migration runs as passes that each make small edits that never overlap, with every finding kept on its pasted line. A class is read in the tag it sits on, so data-[state=open] becomes data-popup-open on a trigger, data-panel-open on an accordion trigger and data-open on the popup. A nested asChild (a tooltip trigger around a dialog trigger) is resolved innermost first.

    It cannot see a handler that used the Radix event argument, a positioning prop spread through ...props, or how a delay should feel - that is the review, which also writes the behavior changes and the hand checks for the .migration report. The page re-scans the rewritten file, so a Radix part left behind is flagged rather than trusted, and every component keeps its name.