How to Migrate from Material UI to Chakra UI — Component Mapping Guide
Last updated: April 2026 · 10 min read
Why Migrate from Material UI to Chakra UI?
Material UI (MUI) and Chakra UI are two of the most popular React component libraries, but they take fundamentally different approaches to component design. Teams often consider migrating from MUI to Chakra when they need a lighter-weight solution with better developer experience and more composable primitives.
Bundle size matters. MUI ships a comprehensive design system that includes Emotion for CSS-in-JS, a full icon library, and deep Material Design integration. Chakra UI takes a leaner approach, offering a smaller core with tree-shakeable utilities. For teams building performance-critical applications, the difference in initial bundle size can translate directly to improved Core Web Vitals scores and better Lighthouse performance metrics.
Developer experience and composability. Chakra UI was built with a "style props" philosophy where layout, spacing, color, and typography are controlled directly through component props rather than external sx objects or makeStyles calls. This means less context-switching between your component logic and your styling code. Props like mt=4, bg="gray.100", and borderRadius="lg" make prototyping dramatically faster.
Theming flexibility.While MUI’s theming system is deeply tied to the Material Design specification (with concepts like elevation, ripple effects, and specific spacing scales), Chakra UI offers a more agnostic token-based theming system. This gives design teams greater freedom to express a unique brand identity without constantly overriding opinionated Material Design defaults.
Accessibility out of the box. Both libraries prioritize accessibility, but Chakra UI bakes ARIA patterns directly into every component without requiring extra configuration. Modals trap focus by default, form inputs announce errors correctly, and interactive elements ship with proper keyboard navigation. This can significantly reduce the a11y audit work required during a migration.
Component Mapping: MUI to Chakra UI
Below is a detailed mapping of the most commonly used Material UI components and their Chakra UI equivalents. Each example shows the MUI source code on the left and the corresponding Chakra UI code on the right. You can also use the FrontFamily Converter to automate these transformations instantly.
Button
<Button variant="contained" color="primary"> Save Changes </Button>
<Button variant="solid" colorScheme="blue"> Save Changes </Button>
TextField → Input
<TextField label="Email" variant="outlined" fullWidth helperText="Enter your email" />
<FormControl> <FormLabel>Email</FormLabel> <Input variant="outline" width="100%" /> <FormHelperText>Enter your email</FormHelperText> </FormControl>
Card → Box
<Card elevation={2}>
<CardContent>
<Typography variant="h6">Title</Typography>
<Typography variant="body2">Content</Typography>
</CardContent>
</Card><Box borderRadius="lg" boxShadow="md" p={5}>
<Heading size="md">Title</Heading>
<Text fontSize="sm">Content</Text>
</Box>Typography → Text / Heading
<Typography variant="h4">Heading</Typography> <Typography variant="body1">Paragraph</Typography> <Typography variant="caption">Small text</Typography>
<Heading size="lg">Heading</Heading> <Text>Paragraph</Text> <Text fontSize="xs">Small text</Text>
Dialog → Modal
<Dialog open={isOpen} onClose={handleClose}>
<DialogTitle>Confirm</DialogTitle>
<DialogContent>
Are you sure?
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
</DialogActions>
</Dialog><Modal isOpen={isOpen} onClose={handleClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Confirm</ModalHeader>
<ModalBody>Are you sure?</ModalBody>
<ModalFooter>
<Button onClick={handleClose}>Cancel</Button>
</ModalFooter>
</ModalContent>
</Modal>Chip → Badge / Tag
<Chip label="Active" color="success" /> <Chip label="Admin" variant="outlined" />
<Badge colorScheme="green">Active</Badge> <Tag variant="outline">Admin</Tag>
Avatar
<Avatar src={user.avatar} alt={user.name} />
<Avatar>{user.initials}</Avatar><Avatar src={user.avatar} name={user.name} />
<Avatar name={user.initials} />Prop Conversion Reference
Beyond component name changes, migrating from MUI to Chakra requires mapping MUI-specific props to their Chakra equivalents. Here are the most common prop transformations you will encounter during a migration:
| MUI Prop | Chakra Equivalent | Notes |
|---|---|---|
variant="contained" | variant="solid" | Primary filled button style |
variant="outlined" | variant="outline" | Border-only variant |
color="primary" | colorScheme="blue" | Semantic color mapping |
disabled | isDisabled | Boolean prop rename |
fullWidth | width="100%" | Style prop instead of boolean |
elevation={2} | boxShadow="md" | Numeric to named token |
size="small" | size="sm" | Abbreviated size tokens |
sx={{ mt: 2 }} | mt={2} | Direct style props, no wrapper |
Step-by-Step Migration Strategy
Migrating an entire codebase from Material UI to Chakra UI is a significant undertaking. Here is a proven strategy that minimizes risk and allows your team to deliver incrementally:
Step 1: Install Chakra UI alongside MUI
Both libraries can coexist in the same project. Install Chakra UI and its peer dependencies (@chakra-ui/react, @emotion/react, framer-motion) without removing MUI. Wrap your app with both ThemeProvider and ChakraProvider. This lets you migrate component by component without a big-bang rewrite.
Step 2: Start with leaf components
Begin by converting the simplest, most isolated components first: buttons, badges, avatars, and typography elements. These have few dependencies and their conversion is straightforward. Each successful conversion builds team confidence and establishes patterns for the more complex components that come later.
Step 3: Migrate form components
Form components (TextField to Input, Select, Checkbox, Radio) are where MUI and Chakra diverge most significantly. MUI bundles label, helper text, and error state into a single component, while Chakra uses composition with FormControl, FormLabel, and FormHelperText. Plan for this structural change by creating wrapper components if needed.
Step 4: Convert layout and complex components
Tackle Grid, Dialog/Modal, Drawer, Tabs, and Accordion last. These often have deeply nested children and complex state management. Use the converter tool to generate initial scaffolding and then refine the output for your specific use case.
Step 5: Migrate the theme
Once all components are converted, port your MUI theme configuration to Chakra’s extendThemeformat. Map your palette colors, typography scale, breakpoints, and component style overrides. Remove MUI’s ThemeProvider and uninstall all @mui/* packages. Run a final audit to catch any remaining MUI imports.
Interactive Component Reference
Search any Material UI component to find its Chakra UI equivalent. Components marked with ⚠ have no direct replacement and require custom implementation.
| Material UI | Chakra UI | Props / Notes | |
|---|---|---|---|
Buttonvariant, color, disabled, startIcon | Buttonvariant, colorScheme, isDisabled, leftIcon | variant="contained" becomes variant="solid"; color="primary" becomes colorScheme="blue" | |
TextFieldlabel, variant, fullWidth, helperText, error | Inputvariant, width, isInvalid | Wrap with FormControl + FormLabel + FormHelperText for labels and helper text | |
Cardelevation, variant | BoxboxShadow, borderRadius, p | No dedicated Card component; use Box with shadow and padding | |
Typographyvariant, gutterBottom, color | Text / HeadingfontSize, mb, color | Use Heading for h1-h6 variants, Text for body/caption | |
Dialogopen, onClose, fullWidth, maxWidth | ModalisOpen, onClose, size | Requires ModalOverlay, ModalContent, ModalHeader, ModalBody, ModalFooter sub-components | |
Chiplabel, color, variant, onDelete | Badge / TagcolorScheme, variant | Use Badge for status indicators, Tag for removable labels | |
Avatarsrc, alt, sx | Avatarsrc, name, size | Chakra generates initials from the name prop automatically | |
Switchchecked, onChange, color | SwitchisChecked, onChange, colorScheme | Boolean prop rename: checked to isChecked | |
Alertseverity, variant, onClose | Alertstatus, variant | Requires AlertIcon, AlertTitle, AlertDescription sub-components | |
Selectvalue, onChange, label | Selectvalue, onChange, placeholder | Uses native <option> children instead of MenuItem components | |
CircularProgresssize, color, variant | Spinnersize, color, thickness | Simpler API; no determinate variant in Chakra | |
LinearProgressvalue, variant, color | Progressvalue, colorScheme, hasStripe | hasStripe and isAnimated replace MUI buffer/indeterminate variants | |
Tooltiptitle, placement, arrow | Tooltiplabel, placement, hasArrow | Nearly identical API with minor prop renames | |
Dividerorientation, variant | Dividerorientation, variant | Direct equivalent with same props | |
Tabsvalue, onChange, variant | Tabsindex, onChange, variant | Uses TabList + Tab and TabPanels + TabPanel compound components | |
DataGridrows, columns, pageSize | No direct equivalent | No built-in data grid; use react-table or AG Grid with Chakra styling | |
Autocompleteoptions, renderInput, onChange | No direct equivalent | No built-in autocomplete; use downshift or react-select with Chakra theme | |
Draweropen, onClose, anchor | DrawerisOpen, onClose, placement | anchor="left" becomes placement="left"; requires DrawerOverlay and DrawerContent | |
MenuanchorEl, open, onClose | MenuisOpen, onClose | Uses MenuButton trigger instead of anchorEl ref pattern | |
Snackbaropen, autoHideDuration, message | useToast()title, description, duration, status | Hook-based API instead of component; call toast() from event handlers | |
StepperactiveStep, orientation | No direct equivalent | No built-in stepper; implement with Steps from chakra-ui-steps community package | |
Accordionexpanded, onChange | AccordionallowToggle, allowMultiple | Uses AccordionItem, AccordionButton, AccordionPanel compound components | |
Breadcrumbsseparator, maxItems | Breadcrumbseparator, spacing | Uses BreadcrumbItem and BreadcrumbLink sub-components | |
Paginationcount, page, onChange | No direct equivalent | No built-in pagination; implement with Button group or use a community package | |
InputAdornmentposition | InputGroupchildren | Use InputLeftElement / InputRightElement inside InputGroup | |
FormControlLabelcontrol, label, labelPlacement | FormControlchildren | Use FormLabel alongside the input component inside FormControl | |
Paperelevation, variant | BoxboxShadow, bg, borderRadius | No Paper equivalent; use Box with shadow and background color | |
Skeletonvariant, width, height | Skeletonwidth, height, startColor, endColor | Similar API; Chakra also has SkeletonText and SkeletonCircle | |
Ratingvalue, onChange, max | No direct equivalent | No built-in rating component; use a community package or custom implementation |
What Developers Actually Hit
Based on migration reports from engineering teams. These are the problems documentation doesn’t warn you about.
MUI’s sx={{ display: 'flex', gap: 2, p: 3 }} has no direct Chakra equivalent. Chakra uses individual style props (display="flex" gap={2} p={3}), but the shorthand values differ — MUI’s spacing unit is 8px, Chakra’s is 4px. So gap: 2 in MUI = 16px, but gap={2} in Chakra = 8px. Every spacing value needs recalculating, not just copying.
MUI’s theme.palette.primary.main becomes Chakra’s theme.colors.blue.500. Teams that abstracted theme tokens behind a shared interface find their entire design token system needs remapping. The token structure is not just renamed — it’s a different shape, and automated find-and-replace won’t handle nested object paths.
Teams that relied on @mui/x-data-grid (sorting, filtering, virtualization, column reorder) discover Chakra has no table component with comparable functionality. They end up keeping DataGrid alongside Chakra or adopting TanStack Table, which requires building the entire UI layer from scratch — header rendering, row virtualization, pagination controls, and filter popups.
MUI’s Emotion-based styles use && for specificity boosting. When both MUI and Chakra run on the same page during incremental migration, CSS injection order causes flickering and style conflicts. The fix: set prepend: true on Emotion’s cache for MUI so its styles are injected before Chakra’s, giving Chakra’s styles natural precedence.
Convert MUI to Chakra UI instantly
Skip the manual work. Paste your Material UI code into the FrontFamily Converter and get production-ready Chakra UI output with correct imports, prop mappings, and component restructuring. A pre-loaded Card example is ready for you to try.
Open Converter with MUI → Chakra ExampleCommon Pitfalls When Migrating MUI to Chakra
CSS specificity conflicts. Running both MUI and Chakra simultaneously can lead to CSS-in-JS specificity battles. Both libraries inject styles at runtime, and Emotion (used by both) may interleave stylesheets. To prevent visual glitches, ensure your Chakra provider is nested inside the MUI provider during the transition period, and use the cssVarsRoot option in Chakra to scope CSS variables.
Icon library differences. MUI uses @mui/icons-material with 2,000+ icons. Chakra does not ship its own icon set. Plan to adopt react-icons or lucide-react as a replacement, and create a mapping file for the icons your project currently uses.
Testing updates. If your tests reference MUI component class names (e.g., .MuiButton-root), those selectors will break when components are converted. Refactor your tests to use data-testid attributes or accessible queries (getByRole) before starting the migration.
Import Changes at a Glance
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import { Card, CardContent } from '@mui/material';
import Typography from '@mui/material/Typography';
import Dialog from '@mui/material/Dialog';import { Button } from '@chakra-ui/react';
import { Input } from '@chakra-ui/react';
import { Box } from '@chakra-ui/react';
import { Text, Heading } from '@chakra-ui/react';
import { Modal } from '@chakra-ui/react';