Migrating from Chakra UI / Mantine / MUI
This is the highest-friction migration Wire UI documents, because it’s a change of model, not a rename. Chakra, Mantine, and MUI are batteries-included: they own styling through a theme object and a runtime CSS engine (Emotion), and you configure components with style props (colorScheme, variant, sx). Wire UI is headless: it ships zero CSS and exposes behavior + data-* state, and you own the visual layer.
So there’s no codemod — the APIs are too different. Instead, this guide is about the shift and a strategy to make it incremental.
Framework note. Chakra (with a separate Vue port), Mantine, and MUI are React-first. Wire UI’s headless model is the same in React, Vue, and Solid — the wrapper pattern below works identically in each; toggle the picker to see your framework’s syntax (
classNamevsclass, props vsdefineProps).
What actually changes
<Button colorScheme="blue" size="lg">) become your classes or a styled wrapper. No Emotion runtime — styling is Tailwind or plain CSS.Box, Stack, Flex, Grid, Typography, Table have no Wire UI equivalent — they’re CSS. Replace them with Tailwind utilities or your own elements.data-* attributes you target in CSS.Component map
The interactive components map fairly directly — it’s the styling that moves, not the structure.
| Concept | Chakra UI | Mantine | MUI | Wire UI |
|---|---|---|---|---|
| Button | Button | Button | Button | Button |
| Dialog | Modal | Modal | Dialog | Modal |
| Drawer | Drawer | Drawer | Drawer | Drawer |
| Menu | Menu | Menu | Menu | Dropdown |
| Select | Select | Select | Select | Select |
| Autocomplete | AutoComplete¹ | Autocomplete | Autocomplete | Combobox |
| Tabs | Tabs | Tabs | Tabs | Tabs |
| Accordion | Accordion | Accordion | Accordion | Accordion |
| Tooltip | Tooltip | Tooltip | Tooltip | Tooltip |
| Popover | Popover | Popover | Popover | Popover |
| Switch | Switch | Switch | Switch | Switch |
| Checkbox / Radio | Checkbox / Radio | Checkbox / Radio | Checkbox / Radio | Checkbox / Radio |
| Slider | Slider | Slider | Slider | Slider |
| Progress | Progress | Progress | LinearProgress | ProgressBar |
| Notifications | useToast | notifications | Snackbar | Toast |
| Stepper | Stepper¹ | Stepper | Stepper | Stepper |
| Pagination | — | Pagination | Pagination | Pagination |
| Avatar / Badge / Card | ✓ | ✓ | ✓ | Avatar / Badge / Card |
¹ Chakra ships these via separate packages or community add-ons. Layout primitives (Box/Stack/Grid) and Table have no Wire UI equivalent — use CSS/Tailwind.
Translating a styled component
Move the style props into a wrapper so the rest of your app barely changes. A styled-library Button (e.g. MUI’s <Button variant="contained" color="primary" size="large">) becomes one styled Wire UI Button whose wrapper mirrors your old prop names:
import { Button as WireButton } from '@wire-ui/react'
const styles = {
contained: 'bg-blue-600 text-white hover:bg-blue-700 shadow',
outlined: 'border border-blue-600 text-blue-600 hover:bg-blue-50',
text: 'text-blue-600 hover:bg-blue-50',
}
export function Button({ variant = 'contained', className = '', ...props }) {
return (
<WireButton
className={`inline-flex items-center rounded-md px-4 py-2 font-medium
focus-visible:ring-2 focus-visible:ring-blue-500 disabled:opacity-50
${styles[variant]} ${className}`}
{...props}
/>
)
}Build these wrappers once, keyed to your old prop names, and most call sites migrate with just an import change.
Strategy
A model change is best done incrementally — don’t attempt a big-bang rewrite.
Button/Modal/Select wrapper with your existing prop names lets app code migrate with minimal churn.Stack/Box/Grid for fl/grid utilities as you touch each surface.Is this migration worth it?
Switch when you want control and portability over convenience: a smaller, runtime-CSS-free bundle, design that isn’t fighting a theme system, AI-native primitives these libraries don’t have, and one component layer across React, Vue, and Solid. If a styled library’s defaults already serve you and you don’t need those, there’s no urgency — Wire UI can also be adopted just for the primitives that are missing.
See the API Parity matrix for the full component list and Data Attributes for the styling hooks that replace style props.