# Material-UI v6 Migration: Key Breaking Changes from v5

> Explore Material-UI v6 migration breaking changes from v5. Learn about UMD bundle removal, Grid2 API updates, LoadingButton consolidation, and component behavior changes to update your code.

- Repository: [MUI/material-ui](https://github.com/mui/material-ui)
- Tags: migration-guide
- Published: 2026-02-26

---

**Material-UI v6 removes the UMD bundle, stabilizes the Grid2 API with new prop structures, consolidates LoadingButton into the core Button, and updates component behaviors like Accordion headings and ListItem composition that require manual code updates or codemods to migrate safely from v5.**

Material-UI v6 introduces a focused set of breaking changes designed to modernize the library, reduce bundle size, and prepare for React 19 and Server Component support. This guide examines the specific API adjustments implemented in the `mui/material-ui` repository that you must address when upgrading from v5, referencing the official migration guide at [`docs/data/material/migration/upgrade-to-v6/upgrade-to-v6.md`](https://github.com/mui/material-ui/blob/main/docs/data/material/migration/upgrade-to-v6/upgrade-to-v6.md).

## Grid2 API Stabilization and Prop Restructuring

The most significant component-level change in Material-UI v6 migration involves the stabilization of the Grid2 component, previously exported as `Unstable_Grid2`.

### Removal of the Unstable Prefix

As implemented in [`packages/mui-material/src/Grid2/Grid2.js`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/Grid2/Grid2.js), the component is now stable and imports must change from `@mui/material/Unstable_Grid2` to `@mui/material/Grid2` (or `{ Grid2 }` from the main package).

### New size and offset Object Syntax

The responsive breakpoint props (`xs`, `sm`, `md`, `lg`, `xl`) and offset props (`xsOffset`, `smOffset`, etc.) are replaced by unified `size` and `offset` objects. According to the source code, the old flat prop structure is no longer supported.

Update your JSX from the v5 syntax:

```tsx
// v5 - No longer valid
<Grid2 xs={12} sm={6} xsOffset={2} />

```

To the v6 object-based approach:

```tsx
import { Grid2 } from '@mui/material';

// v6 - Correct syntax
<Grid2
  size={{ xs: 12, sm: 6 }}
  offset={{ xs: 2 }}
/>

```

### CSS Gap-Based Spacing

Grid2 now uses the CSS `gap` property for spacing instead of the previous implementation. The `disableEqualOverflow` prop has been removed, and grids no longer automatically grow to full width. You must explicitly control sizing via the `size` prop.

### Grid2 Migration Codemod

The repository provides an automated migration path via [`packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.js`](https://github.com/mui/material-ui/blob/main/packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.js). Run this codemod to automatically convert imports and prop structures:

```bash
npx @mui/codemod v6.0.0/grid-v2-props <path>

```

## Button and ListItem Composition Changes

Material-UI v6 consolidates button-related functionality and removes legacy ListItem behaviors that duplicated button capabilities.

### LoadingButton Removal and Core Button Loading State

As of v6.4.0, the `LoadingButton` component from `@mui/lab` has been removed. The loading state is now a core feature of the standard `Button` component. The source file [`packages/mui-material/src/LoadingButton/LoadingButton.js`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/LoadingButton/LoadingButton.js) no longer exists in v6.

Migrate by changing your imports and component usage:

```tsx
import Button from '@mui/material/Button';

// Replace <LoadingButton loading ... /> with:
<Button loading variant="contained">
  Submit
</Button>

```

### ListItem Prop Removal and ListItemButton Migration

The `ListItem` component in [`packages/mui-material/src/ListItem/ListItem.js`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/ListItem/ListItem.js) no longer accepts the `button`, `autoFocus`, `disabled`, or `selected` props. These features are now exclusively handled by `ListItemButton`.

Update your code to use the dedicated component and import its classes from the new location:

```tsx
import ListItemButton from '@mui/material/ListItemButton';
import { listItemButtonClasses } from '@mui/material/ListItemButton';

// Replace <ListItem button selected ... />
<ListItemButton selected className={listItemButtonClasses.root}>
  Item Text
</ListItemButton>

```

The codemod at [`packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js`](https://github.com/mui/material-ui/blob/main/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js) automates this conversion:

```bash
npx @mui/codemod v6.0.0/list-item-button-prop <path>

```

## Component DOM and Accessibility Updates

Several components underwent DOM structure changes to improve accessibility and semantic correctness.

### AccordionSummary Heading Structure

The `AccordionSummary` component, as implemented in [`packages/mui-material/src/Accordion/Accordion.js`](https://github.com/mui/material-ui/blob/main/packages/mui-material/src/Accordion/Accordion.js), is now wrapped in a default `<h3>` heading element (which contains the button element). This affects CSS selectors and accessibility trees.

If you need to change the heading level for semantic hierarchy, use the new `slotProps.heading.component` API:

```tsx
import AccordionSummary from '@mui/material/AccordionSummary';

<AccordionSummary
  expandIcon={<ExpandMoreIcon />}
  slotProps={{ heading: { component: 'h4' } }}  // Changes from h3 to h4
>
  Section Title
</AccordionSummary>

```

### Divider Vertical Element Change

Vertical `Divider` components now render as `<div>` elements instead of `<hr>`. Update any CSS selectors that target the `hr` tag specifically:

```css
/* v5 - No longer matches */
.MuiDivider-vertical hr { ... }

/* v6 - Use the root class instead */
.MuiDivider-root.MuiDivider-vertical { ... }

```

### Chip Focus Retention Behavior

The `Chip` component now retains focus when the **Esc** key is pressed, whereas v5 blurred the component. If your application logic depends on the previous blur behavior, implement a custom `onKeyUp` handler to manually blur the element.

### Autocomplete onInputChange Reason Values

The `onInputChange` callback in `Autocomplete` now receives additional `reason` values: `"blur"`, `"selectOption"`, and `"removeOption"`. Update your event handlers to account for these new cases:

```tsx
<Autocomplete
  onInputChange={(event, value, reason) => {
    if (reason === 'blur' || reason === 'selectOption') {
      // Handle new v6 reasons
    }
  }}
/>

```

## Infrastructure and Type System Changes

Material-UI v6 migration requires updates to your build configuration and type definitions.

### UMD Bundle Removal

The UMD bundle is no longer distributed. Applications using UMD must switch to ESM-based imports or CDN alternatives like [`esm.sh`](https://github.com/mui/material-ui/blob/main/esm.sh). This change affects how you load the library in browser environments without a bundler.

### Typography Color Prop Removal

The `color` prop is no longer a system prop on `Typography`. Custom colors must now be applied via the `sx` prop:

```tsx
import Typography from '@mui/material/Typography';

// v5 - Removed
<Typography color="primary.main">

// v6 - Correct approach
<Typography sx={{ color: theme => theme.palette.primary.main }}>

```

### Box Component Prop Restriction

The `component` prop has been removed from `BoxOwnProps` type definitions. When extending or styling `Box`, use a native element wrapper or type casting as described in the migration guide.

### useMediaQuery Type Cleanup

Deprecated type aliases (`MuiMediaQueryList`, `MuiMediaQueryListEvent`, `MuiMediaQueryListListener`) have been removed from the `useMediaQuery` hook. Use standard DOM types (`MediaQueryList`, `MediaQueryListEvent`) instead.

### CssVarsProvider Stabilization

The experimental prefixes have been dropped from `CssVarsProvider` and `extendTheme`. Import these utilities directly without the `experimental_` prefix:

```tsx
import { CssVarsProvider, extendTheme } from '@mui/material/styles';

```

## Theming and Testing Adjustments

### Color-Mode Utility Replacement

The `theme.palette.mode` property usage for conditional styling is replaced by the `theme.applyStyles()` method. Update your theme overrides:

```tsx
// v5 - Deprecated pattern
sx={{
  color: theme.palette.mode === 'dark' ? '#fff' : '#000',
}}

// v6 - Modern approach
sx={{
  ...theme.applyStyles('dark', { color: '#fff' }),
  ...theme.applyStyles('light', { color: '#000' }),
}}

```

The codemod at [`packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.js`](https://github.com/mui/material-ui/blob/main/packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.js) handles this conversion automatically:

```bash
npx @mui/codemod v6.0.0/theme-v6 <path>

```

### Ripple Effect Testing Requirements

Performance optimizations to the ripple effect require updates to your test suites. Interaction calls that fire events on buttons, checkboxes, chips, and other ripple-enabled components must now be wrapped in `act` and awaited:

```tsx
import { act } from 'react-dom/test-utils';

await act(async () => {
  fireEvent.click(button);
});

```

## Automating Migration with Codemods

The `mui/material-ui` repository provides three primary codemods to streamline your Material-UI v6 migration:

1. **`grid-v2-props`** ([`packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.js`](https://github.com/mui/material-ui/blob/main/packages/mui-codemod/src/v6.0.0/grid-v2-props/grid-v2-props.js)) - Updates Grid2 imports and converts breakpoint props to the new object syntax.
2. **`list-item-button-prop`** ([`packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js`](https://github.com/mui/material-ui/blob/main/packages/mui-codemod/src/v6.0.0/list-item-button-prop/list-item-button-prop.js)) - Transforms `ListItem` button props into `ListItemButton` components.
3. **`theme-v6`** ([`packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.js`](https://github.com/mui/material-ui/blob/main/packages/mui-codemod/src/v6.0.0/theme-v6/theme-v6.js)) - Converts `theme.palette.mode` checks to `theme.applyStyles()` calls.

Run these codemods before manual adjustments to minimize migration effort.

## Summary

- **Grid2** requires updating imports from `Unstable_Grid2` to `Grid2` and converting responsive props (`xs`, `sm`) to the new `size` and `offset` object syntax.
- **LoadingButton** from `@mui/lab` is removed; use the core `Button` component with the `loading` prop instead.
- **ListItem** no longer accepts `button`, `selected`, `disabled`, or `autoFocus` props; migrate to `ListItemButton` and import `listItemButtonClasses` from the new location.
- **AccordionSummary** now renders within an `<h3>` by default; use `slotProps.heading.component` to customize the heading level.
- **Typography** removes the `color` system prop; apply custom colors via the `sx` prop.
- **UMD bundles** are discontinued; switch to ESM imports or modern CDN providers.
- **Testing** requires wrapping ripple interactions in `act` and awaiting them due to performance optimizations.

## Frequently Asked Questions

### How do I migrate Grid2 from Material-UI v5 to v6?

Run the `grid-v2-props` codemod to automatically convert `Unstable_Grid2` imports to `Grid2` and transform flat breakpoint props like `xs={12}` into the object syntax `size={{ xs: 12 }}`. After running the codemod, verify that spacing behaves correctly since Grid2 now uses CSS `gap` and no longer expands to full width by default.

### What happened to LoadingButton in Material-UI v6?

`LoadingButton` was removed from `@mui/lab` in v6.4.0 and its functionality was merged into the core `Button` component. Change your imports from `@mui/lab/LoadingButton` to `@mui/material/Button` and add the `loading` prop to enable the loading state with the circular progress indicator.

### Why did my ListItem buttons stop working after upgrading to v6?

The `button`, `selected`, `disabled`, and `autoFocus` props were removed from `ListItem` to enforce proper component composition. You must replace `<ListItem button ... />` with `<ListItemButton ... />` and update any class imports to use `listItemButtonClasses` from `@mui/material/ListItemButton`. The `list-item-button-prop` codemod automates this migration.

### How do I handle dark mode styling without theme.palette.mode in v6?

Material-UI v6 introduces `theme.applyStyles()` as the preferred method for color-mode-specific styling. Replace conditional logic checking `theme.palette.mode` with `theme.applyStyles('dark', { ... })` or `theme.applyStyles('light', { ... })`. The `theme-v6` codemod can automate this conversion across your codebase.