The package layout has been updated, and now unambiguously supports both valid ESM and CommonJS through the
exports
field in
package.json
.
You can read more about package exports in the
Node.js documentation
.
This update fixes several issues with popular bundlers like Vite and webpack, and makes it possible to load MUI packages from ES modules under Node.js.
Material UI v7 features other quality-of-life improvements, including:
Standardization of the slot pattern across all components
CSS layers support via the
enableCssLayer
prop in
StyledEngineProvider
for client-side apps, and
AppRouterCacheProvider
for Next.js App Router apps
Removed deprecated APIs to reduce the API surface and make the docs easier to navigate
If you're using any of these packages, you should also update their versions to
"7.0.0"
:
@mui/icons-material
@mui/system
@mui/lab
@mui/material-nextjs
@mui/styled-engine
@mui/styled-engine-sc
@mui/utils
Note that MUI X packages
do not
follow the same versioning strategy as Material UI.
If you're using any of the following packages, they should remain unchanged during the upgrade process:
We will not change the minimum supported version in a minor version of Material UI.
However, we recommend not using a TypeScript version older than the lowest supported version by DefinitelyTyped.
For
@types/react*
packages, make sure they are the same major version as the
react
you are using.
Use the snippet below to update your project if needed (replace the
<version>
with the major version of
react
you are using):
Material UI v7 uses
react-is@19
, which changed how React elements are identified.
If you're on React 18 or below, mismatched versions of
react-is
can cause runtime errors in prop type checks.
Forcing
react-is
to match your React version prevents these errors.
Since v7 is a new major release, it contains some changes that affect the public API.
The steps you need to take to migrate from Material UI v6 to v7 are described below.
The package layout has been updated to use the Node.js exports field. This brings several changes:
Deep imports with more than one level are no longer working, at all (they were already considered private API). For example:
-import createTheme from '@mui/material/styles/createTheme';
+import { createTheme } from '@mui/material/styles';
This was never officially supported, but now it will be restricted by bundlers and runtimes.
Modern bundles have also been removed, as the potential for a smaller bundle size is no longer significant.
If you've configured aliases for these bundles, you must remove them now.
Earlier versions of this guide mention the existence of a
mui-modern
conditional exports.
This has since been removed.
This is a non-breaking change, and your bundler will fall back to the ESM bundle.
If you are using a Vite alias to force ESM imports for the icons package, you should remove it as it's no longer necessary:
If you are augmenting the theme and using declarations for nested imports, you should replace them with
@mui/material/styles
. You may also have to rename an interface as some are exported from
@mui/material/styles
under a different name:
The deprecated
Grid
component has been renamed to
GridLegacy
.
The
Grid2
component has been moved to the
Grid
namespace.
Depending on your project, you may follow one of the following approaches:
If you are using the deprecated grid and wish to upgrade,
run the following codemod:
The
size
prop for
InputLabel
now follows the standard naming convention used across other components like
Button
and
TextField
.
'normal'
has been replaced with
'medium'
for consistency.
If you were using
size="normal"
, update it to
size="medium"
:
Note:
Because the default size of
InputLabel
was changed from
normal
to
medium
, the class
MuiInputLabel‑sizeMedium
is no longer added. If you relied on this class for custom styling, use a different class.
The default
data-testid
prop has been removed from the icons in
@mui/icons-material
in production bundles. This change ensures that the
data-testid
prop is only defined where needed, reducing the potential for naming clashes and removing unnecessary properties in production.
The import path for the types has changed from
@mui/material/TablePagination/TablePaginationActions
to
@mui/material/TablePaginationActions
.
- import type { TablePaginationActionsProps } from '@mui/material/TablePagination/TablePaginationActions';
+ import type { TablePaginationActionsProps } from '@mui/material/TablePaginationActions';
When CSS theme variables is enabled with built-in light and dark color schemes, the theme no longer changes between modes.
The snippet below demonstrates this behavior when users toggle the dark mode, the
mode
state from
useColorScheme
changes, but the theme object no longer changes:
import{
ThemeProvider,
createTheme,
useTheme,
useColorScheme,}from'@mui/material/styles';const theme =createTheme({
cssVariables:{colorSchemeSelector:'class',colorSchemes:{light:true,dark:true,});
console.log(theme.palette.mode);// 'light' is the default modefunctionColorModeToggle(){const{ setMode, mode }=useColorScheme();const theme =useTheme();
React.useEffect(()=>{
console.log(mode);// logged 'light' at first render, and 'dark' after the button click},[mode]);
React.useEffect(()=>{// logged 'light' at first render, no log after the button click
console.log(theme.palette.mode);},[theme]);return<buttononClick={()=>setMode('dark')}>Toggle dark mode</button>;functionApp(){return(<ThemeProvidertheme={theme}><ColorModeToggle/></ThemeProvider>
This default behavior was made to improve performance by avoiding unnecessary re-renders when the mode changes.
It's recommended to use the
theme.vars.*
as values in your styles to refer to the CSS variables directly:
If you need to do runtime calculations, we recommend using CSS instead of JavaScript whenever possible.
For example, adjusting the alpha channel of a color can be done using the
color-mix
function
:
If any of the methods above do not suit your project, you can opt out from this behavior by passing the
forceThemeRerender
prop to the ThemeProvider component:
APIs that were deprecated in v5 have been removed in v7.
createMuiTheme function
The deprecated
createMuiTheme
function has been removed.
Use
createTheme
instead.
-import { createMuiTheme } from '@mui/material/styles';
+import { createTheme } from '@mui/material/styles';
Dialog's onBackdropClick prop
The deprecated
onBackdropClick
prop has been removed from the
Dialog
component.
Please use the
onClose
callback instead, which receives the event and the reason for the dialog closing.
Here's an example of how to use it:
The deprecated
onBackdropClick
prop has been removed from the
Modal
component.
Please use the
onClose
callback instead, which receives the event and the reason for the modal closing.
Here's an example of how to use it:
The deprecated
MuiRating-readOnly
class was removed in favor of
Mui-readOnly
global class.
-.MuiRating-readOnly
+.Mui-readOnly
StepButtonIcon type
The deprecated
StepButtonIcon
type has been removed. Use
StepButtonProps['icon']
instead.
-import { StepButtonIcon } from '@mui/material/StepButton';
+import { StepButtonProps } from '@mui/material/StepButton';
-StepButtonIcon
+StepButtonProps['icon']
StyledEngineProvider import path
Importing
StyledEngineProvider
from
'@mui/material'
was deprecated and now has been removed.
Import it from
'@mui/material/styles'
instead:
-import { StyledEngineProvider } from '@mui/material';
+import { StyledEngineProvider } from '@mui/material/styles';
Lab components moved to the main package
The following
@mui/lab
components and hook have been moved to
@mui/material
:
Alert
AlertTitle
Autocomplete
AvatarGroup
Pagination
PaginationItem
Rating
Skeleton
SpeedDial
SpeedDialAction
SpeedDialIcon
ToggleButton
ToggleButtonGroup
usePagination
To keep using these components and hook, import them from
@mui/material
instead of
@mui/lab
.
-import Alert from '@mui/lab/Alert';
+import Alert from '@mui/material/Alert';
-import { Alert } from '@mui/lab';
+import { Alert } from '@mui/material';
Use this codemod to automatically update the imports: