Ant Design to Material UI Migration — Enterprise React Framework Switch
Last updated: April 2026 · 13 min read
Why Migrate from Ant Design to Material UI?
Ant Design and Material UI are the two heavyweights of the React component library ecosystem, each powering thousands of enterprise applications worldwide. While Ant Design has deep roots in the Chinese tech ecosystem and excels at data-heavy admin interfaces, many international teams are choosing to migrate to Material UI for several compelling reasons.
Material Design ecosystem.Material UI implements Google’s Material Design specification, which is one of the most widely recognized and documented design systems in the world. This means your team has access to extensive design guidelines, Figma kits, and a global community of designers who understand the patterns. Ant Design follows its own design language, which, while excellent, has less adoption outside of Asian markets.
The sx prop and styling flexibility. MUI’s sxprop provides a powerful, type-safe way to apply responsive styles directly to components without leaving your JSX. While Ant Design recently improved its CSS-in-JS story with v5, MUI’s Emotion-based styling system is more mature and offers deeper integration with the component API. The styled() utility, theme overrides, and sx prop give you three complementary ways to customize any component.
Community and ecosystem size. Material UI is the most downloaded React component library on npm, with over 4 million weekly downloads. This translates to more Stack Overflow answers, more tutorials, more third-party integrations, and faster bug fixes. The MUI ecosystem also includes MUI X for advanced components like DataGrid, Date Pickers, and Charts, which are critical for enterprise applications.
Bundle size control. MUI supports tree-shaking out of the box and offers both path-based and named imports. Ant Design has historically struggled with bundle size, requiring plugins like babel-plugin-import to achieve proper tree-shaking. While Ant Design v5 improved this situation, MUI still offers more granular control over what ends up in your production bundle.
Component Mapping: Ant Design to MUI
Below is a detailed mapping of the most commonly used Ant Design components and their Material UI equivalents. Each example shows the Ant Design source on the left and the MUI code on the right. Use the FrontFamily Converter to automate these transformations.
Button (type → variant)
<Button type="primary" size="large"> Save Changes </Button> <Button type="default">Cancel</Button> <Button type="dashed">Add Item</Button>
<Button variant="contained" size="large">
Save Changes
</Button>
<Button variant="outlined">Cancel</Button>
<Button variant="outlined" sx={{ borderStyle: 'dashed' }}>
Add Item
</Button>Input → TextField
<Input
placeholder="Enter email"
prefix={<MailOutlined />}
allowClear
size="large"
/><TextField
placeholder="Enter email"
InputProps={{
startAdornment: (
<InputAdornment position="start">
<MailIcon />
</InputAdornment>
)
}}
size="medium"
/>Tag → Chip
<Tag color="green">Active</Tag>
<Tag color="red" closable
onClose={handleClose}>Error</Tag>
<Tag.CheckableTag checked={checked}
onChange={setChecked}>Feature</Tag.CheckableTag><Chip label="Active" color="success" size="small" />
<Chip label="Error" color="error"
onDelete={handleClose} />
<Chip label="Feature" variant={checked ?
"filled" : "outlined"}
onClick={() => setChecked(!checked)} />Modal → Dialog
<Modal
title="Confirm Action"
open={isOpen}
onOk={handleOk}
onCancel={handleCancel}
okText="Confirm"
cancelText="Cancel">
Are you sure you want to proceed?
</Modal><Dialog open={isOpen} onClose={handleCancel}>
<DialogTitle>Confirm Action</DialogTitle>
<DialogContent>
<DialogContentText>
Are you sure you want to proceed?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleCancel}>Cancel</Button>
<Button onClick={handleOk} variant="contained">
Confirm
</Button>
</DialogActions>
</Dialog>Table → DataGrid
<Table
dataSource={data}
columns={[
{ title: 'Name', dataIndex: 'name',
sorter: true },
{ title: 'Age', dataIndex: 'age' },
{ title: 'Action',
render: (_, record) => (
<Button onClick={() => edit(record)}>
Edit
</Button>
)}
]}
pagination={{ pageSize: 10 }}
/><DataGrid
rows={data}
columns={[
{ field: 'name', headerName: 'Name',
sortable: true },
{ field: 'age', headerName: 'Age' },
{ field: 'action', headerName: 'Action',
renderCell: (params) => (
<Button onClick={() => edit(params.row)}>
Edit
</Button>
)}
]}
pageSize={10}
/>Select
<Select
placeholder="Choose role"
options={[
{ value: 'admin', label: 'Admin' },
{ value: 'user', label: 'User' },
]}
onChange={setRole}
/><FormControl>
<InputLabel>Choose role</InputLabel>
<Select
value={role}
label="Choose role"
onChange={(e) => setRole(e.target.value)}>
<MenuItem value="admin">Admin</MenuItem>
<MenuItem value="user">User</MenuItem>
</Select>
</FormControl>Prop Conversion Reference
Ant Design and MUI use different naming conventions for similar concepts. Here are the most frequent prop transformations you will encounter:
| Ant Design Prop | MUI Equivalent | Notes |
|---|---|---|
type="primary" | variant="contained" | Primary button style |
type="default" | variant="outlined" | Secondary button style |
type="text" | variant="text" | Same name, different prop key |
open | open | Same (Antd v5 aligned with MUI) |
onCancel | onClose | Modal/Dialog close handler |
size="large" | size="large" | Same (but MUI default is medium) |
prefix / suffix | InputAdornment | Wrapper component required |
allowClear | InputProps endAdornment | Manual clear button needed |
Form Handling Migration
Form handling is one of the biggest differences between Ant Design and MUI. Ant Design ships a powerful built-in form system with Form, Form.Item, and Form.useForm. MUI does not include form management, so you need to choose a third-party solution.
Ant Design’s built-in Form
Ant Design’s Form component handles validation, field state, error display, and submission in a single integrated API. Fields are registered via name props on Form.Item, and validation rules are defined inline. This “batteries-included” approach means less boilerplate for standard forms but less flexibility for unconventional patterns.
MUI + React Hook Form
The most popular pairing with MUI is React Hook Form. It provides Controllercomponents that wrap MUI inputs, handling registration, validation, and error state. While this requires more setup than Ant Design’s built-in system, it offers better performance (fewer re-renders) and more flexibility for complex validation scenarios with Zod or Yup schemas.
MUI + Formik
Formik is another popular option that provides a more declarative API with Field and ErrorMessagecomponents. MUI provides official examples for Formik integration, making this a well-documented path. For teams migrating from Ant Design’s form system, Formik’s API will feel more familiar than React Hook Form.
Theme Migration
Token system differences. Ant Design v5 uses a token-based theme system with ConfigProvider and design tokens like colorPrimary, borderRadius, and fontSize. MUI uses createTheme with a deeply nested object structure for palette, typography, spacing, and component overrides. While the concepts are similar, the structure is entirely different and requires manual mapping.
Component-level overrides. Ant Design allows global component customization through ConfigProvider and component-level tokens. MUI achieves this through theme.components, where you can override defaultProps, styleOverrides, and variantsfor every component globally. MUI’s approach is more verbose but gives finer control over every component state and variant.
Dark mode. Ant Design toggles dark mode through the algorithm prop on ConfigProvider, using theme.darkAlgorithm. MUI uses palette.mode: 'dark' in createTheme. Both approaches work well, but MUI gives you more control over individual color values in dark mode through the palette override system.
Interactive Component Reference
Search any Ant Design component to find its Material UI equivalent. Components marked with ⚠ have no direct replacement and require custom implementation.
| Ant Design | Material UI | Props / Notes | |
|---|---|---|---|
Buttontype, danger, icon, loading, size | Buttonvariant, color, startIcon, disabled, size | type="primary" becomes variant="contained"; danger becomes color="error" | |
Inputplaceholder, prefix, suffix, allowClear, size | TextFieldplaceholder, InputProps (InputAdornment), size | prefix/suffix become InputAdornment components inside InputProps | |
Cardtitle, bordered, extra, hoverable, cover | CardCardHeader (title, action), variant, CardMedia | Uses CardHeader for title+action, CardMedia for cover image | |
TypographyTypography.Title (level), Typography.Text (type), Typography.Paragraph | Typographyvariant, color, gutterBottom | Title level={3} becomes variant="h3"; Text type="secondary" becomes color="textSecondary" | |
Modalopen, onOk, onCancel, title, footer, width | Dialogopen, onClose, DialogTitle, DialogActions, maxWidth | Built-in OK/Cancel buttons become manual DialogActions; onCancel becomes onClose | |
Tagcolor, closable, onClose, CheckableTag | Chipcolor, onDelete, variant, onClick | CheckableTag becomes Chip with onClick toggle and variant switch | |
Avatarsrc, alt, size, shape, icon | Avatarsrc, alt, sx (width/height), variant | shape="square" becomes variant="square"; icon becomes children | |
Switchchecked, onChange, disabled, loading, size | Switchchecked, onChange, disabled, size | No loading prop in MUI Switch; implement with overlay spinner if needed | |
Alerttype, message, description, closable, banner | Alertseverity, children, onClose, variant | type becomes severity; message+description become AlertTitle+children | |
Selectoptions, value, onChange, mode, placeholder, allowClear | Selectvalue, onChange, multiple, MenuItem children | options array becomes MenuItem children; mode="multiple" becomes multiple prop | |
TabledataSource, columns, pagination, sorter, filters | DataGridrows, columns, pageSize, sortModel, filterModel | DataGrid from @mui/x-data-grid; column config structure differs significantly | |
AutoCompleteoptions, onSearch, onSelect, value | Autocompleteoptions, onInputChange, onChange, value, renderInput | MUI Autocomplete requires renderInput prop for the TextField; more verbose but more flexible | |
Draweropen, onClose, placement, width, title | Draweropen, onClose, anchor, PaperProps, children | placement becomes anchor; title must be added manually as Typography | |
Menuitems, mode, onClick, selectedKeys | MenuanchorEl, open, onClose, MenuItem, onClick | AntD declarative items array becomes imperative MenuItem children with anchorEl ref | |
messagemessage.success(), message.error(), message.warning() | Snackbaropen, autoHideDuration, onClose, Alert children | Imperative API becomes declarative component; manage open state manually or use notistack | |
TabsactiveKey, onChange, type, items | Tabsvalue, onChange, variant, Tab children | items array becomes Tab component children; type="card" becomes variant="scrollable" | |
Tooltiptitle, placement, trigger | Tooltiptitle, placement | trigger="click" has no equivalent; MUI Tooltip is hover-only (use Popover for click) | |
Dividertype, orientation, children (text) | Dividerorientation, variant, textAlign, children | Both support text content inside the divider line | |
Paginationtotal, current, pageSize, onChange | Paginationcount, page, onChange | AntD uses total items; MUI uses total pages. Calculate: count = Math.ceil(total/pageSize) | |
Breadcrumbitems, separator | Breadcrumbsseparator, children (Link/Typography) | items array becomes Link and Typography children components | |
Stepscurrent, items, direction, size | StepperactiveStep, orientation, Step, StepLabel | items array becomes Step + StepLabel children; direction becomes orientation | |
DatePickervalue, onChange, format, picker | DatePickervalue, onChange, format, views | MUI DatePicker from @mui/x-date-pickers; requires LocalizationProvider wrapper | |
Uploadaction, fileList, onChange, listType | No direct equivalent | No MUI equivalent; use react-dropzone or a custom implementation with MUI styling | |
TreeSelecttreeData, value, onChange, treeCheckable | No direct equivalent | No MUI equivalent; use MUI TreeView for display, but no built-in select behavior | |
Cascaderoptions, onChange, placeholder, expandTrigger | No direct equivalent | No MUI equivalent; implement with nested Menu components or use a community package | |
ConfigProvidertheme, locale, componentSize | ThemeProvidertheme (createTheme) | ConfigProvider tokens map to createTheme palette/typography/components overrides |
What Developers Actually Hit
Based on migration reports from engineering teams. These are the problems documentation doesn’t warn you about.
AntD’s Table API (columns, dataSource, pagination) looks simple but it’s deeply integrated — custom column renderers, row selection, expandable rows, and nested tables all use the same declarative config. MUI’s DataGrid has different APIs for all of these and requires @mui/x-data-grid (separate package, separate license for premium features like column grouping and row pinning).
message.success('Done') and notification.open({...}) are global imperative APIs — call them from anywhere, including utility functions and API interceptors. MUI has Snackbar but it’s a controlled component — you need to manage open state, queue multiple notifications yourself, or adopt a library like notistack to get equivalent imperative behavior.
AntD’s ConfigProvider handles locale, component size, theme, and component defaults in a single wrapper. MUI’s ThemeProvider only handles theme. You need separate solutions for locale (an i18n library like react-intl), default component sizes (custom theme overrides per component in createTheme), and global component configuration (no MUI equivalent — each component must be configured individually).
AntD uses @ant-design/icons with a completely different icon set than MUI’s @mui/icons-material. Every icon reference needs manual mapping — EditOutlined becomes EditIcon, DeleteFilled becomes DeleteIcon, but SettingOutlined becomes SettingsIcon (note the plural). There is no automated way to convert icon names, and a medium-sized app can have 100+ unique icon references.
Convert Ant Design to MUI instantly
Skip the manual work. Paste your Ant Design code into the FrontFamily Converter and get production-ready Material UI output with correct imports, prop mappings, and component restructuring. A pre-loaded form example is ready for you to try.
Open Converter with Ant Design → MUI ExampleImport Changes at a Glance
import { Button } from 'antd';
import { Input } from 'antd';
import { Modal } from 'antd';
import { Table } from 'antd';
import { Tag } from 'antd';import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import Dialog from '@mui/material/Dialog';
import { DataGrid } from '@mui/x-data-grid';
import Chip from '@mui/material/Chip';