secondsky/base-ui-react
MUI Base UI unstyled React components with Floating UI. Use for accessible components, Radix UI migration, render props API, or encountering positioning, popup, v1.0 beta issues.
npx skills add https://github.com/secondsky/claude-skills --skill base-ui-react
Status: Beta (v1.0.0-beta.4) ⚠️ | Last Verified: 2025-11-18
MUI's unstyled, accessible React component library:
Beta status: v1.0.0-beta.4 (stable v1.0 expected Q4 2025)
bun add @base-ui-components/react
import * as Dialog from '@base-ui-components/react/dialog';
export function MyDialog() {
return (
<Dialog.Root>
<Dialog.Trigger>Open</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Backdrop />
<Dialog.Popup>
<Dialog.Title>Title</Dialog.Title>
<Dialog.Description>Content</Dialog.Description>
<Dialog.Close>Close</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
);
}
import * as Select from '@base-ui-components/react/select';
<Select.Root>
<Select.Trigger>
<Select.Value placeholder="Select" />
</Select.Trigger>
<Select.Portal>
<Select.Positioner>
<Select.Popup>
<Select.Option value="1">Option 1</Select.Option>
<Select.Option value="2">Option 2</Select.Option>
</Select.Popup>
</Select.Positioner>
</Select.Portal>
</Select.Root>
Load references/setup-guide.md for complete examples.
Available (27+):
10. Test on target browsers
10. Never assume Radix compatibility (different API)
<Dialog.Popup className="rounded-lg bg-white p-6 shadow-xl dark:bg-gray-800">
<Dialog.Title className="text-xl font-bold text-gray-900 dark:text-white">
Dialog Title
</Dialog.Title>
<Dialog.Description className="mt-2 text-gray-600 dark:text-gray-300">
Dialog content here
</Dialog.Description>
<Dialog.Close className="mt-4 rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600">
Close
</Dialog.Close>
</Dialog.Popup>
<Dialog.Root>
<Dialog.Trigger className="btn">Open Modal</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Backdrop className="fixed inset-0 bg-black/50" />
<Dialog.Popup className="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6">
<Dialog.Title>Confirm Action</Dialog.Title>
<Dialog.Description>Are you sure?</Dialog.Description>
<Dialog.Close>Cancel</Dialog.Close>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
<Select.Root>
<Select.Trigger className="flex items-center gap-2 rounded border px-4 py-2">
<Select.Value placeholder="Select option" />
</Select.Trigger>
<Select.Portal>
<Select.Positioner className="z-50">
<Select.Popup className="rounded border bg-white shadow-lg">
<Select.Option value="1" className="px-4 py-2 hover:bg-gray-100">
Option 1
</Select.Option>
<Select.Option value="2" className="px-4 py-2 hover:bg-gray-100">
Option 2
</Select.Option>
</Select.Popup>
</Select.Positioner>
</Select.Portal>
</Select.Root>
import * as Tooltip from '@base-ui-components/react/tooltip';
<Tooltip.Root>
<Tooltip.Trigger>Hover me</Tooltip.Trigger>
<Tooltip.Portal>
<Tooltip.Positioner>
<Tooltip.Popup className="rounded bg-gray-900 px-2 py-1 text-sm text-white">
Tooltip text
</Tooltip.Popup>
</Tooltip.Positioner>
</Tooltip.Portal>
</Tooltip.Root>
Stable for production:
Use with caution:
Migration path:
| Feature | Base UI | Radix UI |
|---------|---------|----------|
| Pattern | Render props | asChild |
| Positioning | Floating UI built-in | Manual |
| Beta | Yes | Stable |
| Tree-shaking | Better | Good |
| Bundle size | Smaller | Larger |
When to use Base UI:
When to use Radix:
References (references/):
example-reference.md - Detailed component examples and patternsmigration-from-radix.md - Complete migration guide from Radix UI (includes render prop pattern explanation)setup-guide.md - Installation and setup walkthroughTemplates (templates/):
Accordion.tsx - Accordion component with render propsDialog.tsx - Modal dialog exampleNumberField.tsx - Number input with validationPopover.tsx - Popover with positioningSelect.tsx - Select dropdownTooltip.tsx - Tooltip componentmigration-example.tsx - Radix to Base UI migration exampleQuestions? Issues?
references/setup-guide.md for setupTake secondsky/base-ui-react from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.