Skip to content
+

Migrating to the new theme

This guide walks through recent Joy UI default theme upgrades and how to update to it.

With the introduction of Joy UI's v5.0.0-beta.0, its default theme went under some significant restructuring and polish. Several changes were made, including renaming, removing, and adding new tokens. This guide walks through each and every one of them and provides instructions for a smooth migration process.

Color & Typography

Purple palette removed

The purple palette has been removed as we updated the primary color. In case you want to continue using it, copy the snippet below to your project:

const purple = {
  50: '#FDF7FF',
  100: '#F4EAFF',
  200: '#E1CBFF',
  300: '#C69EFF',
  400: '#A374F9',
  500: '#814DDE',
  600: '#5F35AE',
  700: '#452382',
  800: '#301761',
  900: '#1D0A42',
};

Info palette removed

The info palette has been removed to simplify the color set. We've realized that, in most cases, the neutral palette is used for info-related components and use cases. Additionally, we noticed a strong overlap between info and neutral, which motivated further this change.

- <Chip color="info" variant="soft">
+ <Chip color="neutral" variant="soft">

If you want to continue using it, add the palette directly to the theme object file:

import { extendTheme } from '@mui/joy/styles';

const info = {
  50: '#FDF7FF',
  100: '#F4EAFF',
  200: '#E1CBFF',
  300: '#C69EFF',
  400: '#A374F9',
  500: '#814DDE',
  600: '#5F35AE',
  700: '#452382',
  800: '#301761',
  900: '#1D0A42',
};

const theme = extendTheme({
  colorSchemes: {
    light: {
      palette: {
        info: {
          ...info,
          plainColor: `var(--joy-palette-info-600)`,
          plainHoverBg: `var(--joy-palette-info-100)`,
          plainActiveBg: `var(--joy-palette-info-200)`,
          plainDisabledColor: `var(--joy-palette-info-200)`,
          outlinedColor: `var(--joy-palette-info-500)`,
          outlinedBorder: `var(--joy-palette-info-200)`,
          outlinedHoverBg: `var(--joy-palette-info-100)`,
          outlinedHoverBorder: `var(--joy-palette-info-300)`,
          outlinedActiveBg: `var(--joy-palette-info-200)`,
          outlinedDisabledColor: `var(--joy-palette-info-100)`,
          outlinedDisabledBorder: `var(--joy-palette-info-100)`,
          softColor: `var(--joy-palette-info-600)`,
          softBg: `var(--joy-palette-info-100)`,
          softHoverBg: `var(--joy-palette-info-200)`,
          softActiveBg: `var(--joy-palette-info-300)`,
          softDisabledColor: `var(--joy-palette-info-300)`,
          softDisabledBg: `var(--joy-paletteinfo}-50)`,
          solidColor: '#fff',
          solidBg: `var(--joy-palette-info-500)`,
          solidHoverBg: `var(--joy-palette-info-600)`,
          solidActiveBg: `var(--joy-palette-info-700)`,
          solidDisabledColor: `#fff`,
          solidDisabledBg: `var(--joy-palette-info-200)`,
        },
      },
    },
    dark: {
      palette: {
        info: {
          ...info,
          plainColor: `var(--joy-palette-info-300)`,
          plainHoverBg: `var(--joy-palette-info-800)`,
          plainActiveBg: `var(--joy-palette-info-700)`,
          plainDisabledColor: `var(--joy-palette-info-800)`,
          outlinedColor: `var(--joy-palette-info-200)`,
          outlinedBorder: `var(--joy-palette-info-700)`,
          outlinedHoverBg: `var(--joy-palette-info-800)`,
          outlinedHoverBorder: `var(--joy-palette-info-600)`,
          outlinedActiveBg: `var(--joy-palette-info-900)`,
          outlinedDisabledColor: `var(--joy-palette-info-800)`,
          outlinedDisabledBorder: `var(--joy-palette-info-800)`,
          softColor: `var(--joy-palette-info-200)`,
          softBg: `var(--joy-palette-info-900)`,
          softHoverBg: `var(--joy-palette-info-800)`,
          softActiveBg: `var(--joy-palette-info-700)`,
          softDisabledColor: `var(--joy-palette-info-800)`,
          softDisabledBg: `var(--joy-palette-info-900)`,
          solidColor: `#fff`,
          solidBg: `var(--joy-palette-info-600)`,
          solidHoverBg: `var(--joy-palette-info-700)`,
          solidActiveBg: `var(--joy-palette-info-800)`,
          solidDisabledColor: `var(--joy-palette-info-700)`,
          solidDisabledBg: `var(--joy-palette-info-900)`,
        },
      },
    },
  },
});

Then provide the theme to the CssVarsProvider:

import { CssVarsProvider, extendTheme } from '@mui/joy/styles';

const theme = extendTheme({});

function App() {
  return <CssVarsProvider theme={theme}></CssVarsProvider>;
}

TypeScript

If working with TypeScript, add the info palette to the theme's palette types via module augmentation:

// You can put this to any file that's included in your tsconfig
import type { PaletteRange } from '@mui/joy/styles';

declare module '@mui/joy/styles' {
  interface ColorPalettePropOverrides {
    // apply to all Joy UI components that support `color` prop
    info: true;
  }

  interface Palette {
    // this will make the node `info` configurable in `extendTheme`
    // and add `info` to the theme's palette.
    info: PaletteRange;
  }
}

Other palettes

Each and every color of all palettes have been refined for better contrast ratios, vibrance, and personality. Here's a before and after:

    primary (50 - 900)
  • #F4FAFF
    #EDF5FD
  • #DDF1FF
    #E3EFFB
  • #ADDBFF
    #C7DFF7
  • #6FB6FF
    #97C3F0
  • #3990FF
    #4393E4
  • #096BDE
    #0B6BCB
  • #054DA7
    #185EA5
  • #02367D
    #12467B
  • #072859
    #0A2744
  • #00153C
    #051423
    neutral (50 - 900)
  • #F7F7F8
    #FBFCFE
  • #EBEBEF
    #F0F4F8
  • #D8D8DF
    #DDE7EE
  • #B9B9C6
    #CDD7E1
  • #8F8FA3
    #9FA6AD
  • #73738C
    #636B74
  • #5A5A72
    #555E68
  • #434356
    #32383E
  • #25252D
    #171A1C
  • #131318
    #0B0D0E
    danger (50 - 900)
  • #FFF8F6
    #FEF6F6
  • #FFE9E8
    #FCE4E4
  • #FFC7C5
    #F7C5C5
  • #FF9192
    #F09898
  • #FA5255
    #E47474
  • #D3232F
    #C41C1C
  • #A10E25
    #A51818
  • #77061B
    #7D1212
  • #580013
    #430A0A
  • #39000D
    #240505
    success (50 - 900)
  • #F3FEF5
    #F6FEF6
  • #D7F5DD
    #E3FBE3
  • #77EC95
    #C7F7C7
  • #4CC76E
    #A1E8A1
  • #2CA24D
    #51BC51
  • #1A7D36
    #1F7A1F
  • #0F5D26
    #136C13
  • #034318
    #0A470A
  • #002F0F
    #042F04
  • #001D09
    #021D02
    warning (50 - 900)
  • #FFF8C5
    #FEFAF6
  • #FAE17D
    #FDF0E1
  • #EAC54F
    #FCE1C2
  • #D4A72C
    #F3C896
  • #BF8700
    #EA9A3E
  • #9A6700
    #9A5B13
  • #7D4E00
    #72430D
  • #633C01
    #492B08
  • #4D2D00
    #2E1B05
  • #3B2300
    #1D1002
    common (white & black)
  • #FFF
    #FCFCFD
  • #09090D
    #09090B

Keep the old colors

To keep using the old colors, add them to your theme:

Primary
const primary = {
  50: '#F4FAFF',
  100: '#DDF1FF',
  200: '#ADDBFF',
  300: '#6FB6FF',
  400: '#3990FF',
  500: '#096BDE',
  600: '#054DA7',
  700: '#02367D',
  800: '#072859',
  900: '#00153C',
};

extendTheme({
  colorSchemes: {
    light: {
      palette: {
        primary: {
          ...primary,
          plainColor: `var(--joy-palette-primary-600)`,
          plainHoverBg: `var(--joy-palette-primary-100)`,
          plainActiveBg: `var(--joy-palette-primary-200)`,
          plainDisabledColor: `var(--joy-palette-primary-200)`,

          outlinedColor: `var(--joy-palette-primary-500)`,
          outlinedBorder: `var(--joy-palette-primary-200)`,
          outlinedHoverBg: `var(--joy-palette-primary-100)`,
          outlinedHoverBorder: `var(--joy-palette-primary-300)`,
          outlinedActiveBg: `var(--joy-palette-primary-200)`,
          outlinedDisabledColor: `var(--joy-palette-primary-100)`,
          outlinedDisabledBorder: `var(--joy-palette-primary-100)`,

          softColor: `var(--joy-palette-primary-600)`,
          softBg: `var(--joy-palette-primary-100)`,
          softHoverBg: `var(--joy-palette-primary-200)`,
          softActiveBg: `var(--joy-palette-primary-300)`,
          softDisabledColor: `var(--joy-palette-primary-300)`,
          softDisabledBg: `var(--joy-palette-primary}-)50`,

          solidColor: '#fff',
          solidBg: `var(--joy-palette-primary-500)`,
          solidHoverBg: `var(--joy-palette-primary-600)`,
          solidActiveBg: `var(--joy-palette-primary-700)`,
          solidDisabledColor: `#fff`,
          solidDisabledBg: `var(--joy-palette-primary-200)`,
        },
      },
    },
    dark: {
      palette: {
        primary: {
          ...primary,
          plainColor: `var(--joy-palette-primary-300)`,
          plainHoverBg: `var(--joy-palette-primary-800)`,
          plainActiveBg: `var(--joy-palette-primary-700)`,
          plainDisabledColor: `var(--joy-palette-primary-800)`,

          outlinedColor: `var(--joy-palette-primary-200)`,
          outlinedBorder: `var(--joy-palette-primary-700)`,
          outlinedHoverBg: `var(--joy-palette-primary-800)`,
          outlinedHoverBorder: `var(--joy-palette-primary-600)`,
          outlinedActiveBg: `var(--joy-palette-primary-900)`,
          outlinedDisabledColor: `var(--joy-palette-primary-800)`,
          outlinedDisabledBorder: `var(--joy-palette-primary-800)`,

          softColor: `var(--joy-palette-primary-200)`,
          softBg: `var(--joy-palette-primary-900)`,
          softHoverBg: `var(--joy-palette-primary-800)`,
          softActiveBg: `var(--joy-palette-primary-700)`,
          softDisabledColor: `var(--joy-palette-primary-800)`,
          softDisabledBg: `var(--joy-palette-primary-900)`,

          solidColor: `#fff`,
          solidBg: `var(--joy-palette-primary-600)`,
          solidHoverBg: `var(--joy-palette-primary-700)`,
          solidActiveBg: `var(--joy-palette-primary-800)`,
          solidDisabledColor: `var(--joy-palette-primary-700)`,
          solidDisabledBg: `var(--joy-palette-primary-900)`,
        },
      },
    },
  },
});
Neutral
const neutral = {
  50: '#F7F7F8',
  100: '#EBEBEF',
  200: '#D8D8DF',
  300: '#B9B9C6',
  400: '#8F8FA3',
  500: '#73738C',
  600: '#5A5A72',
  700: '#434356',
  800: '#25252D',
  900: '#131318',
};

extendTheme({
  colorSchemes: {
    light: {
      palette: {
        neutral: {
          ...neutral,
          plainColor: `var(--joy-palette-neutral-800)`,
          plainHoverColor: `var(--joy-palette-neutral-900)`,
          plainHoverBg: `var(--joy-palette-neutral-100)`,
          plainActiveBg: `var(--joy-palette-neutral-200)`,
          plainDisabledColor: `var(--joy-palette-neutral-300)`,

          outlinedColor: `var(--joy-palette-neutral-800)`,
          outlinedBorder: `var(--joy-palette-neutral-200)`,
          outlinedHoverColor: `var(--joy-palette-neutral-900)`,
          outlinedHoverBg: `var(--joy-palette-neutral-100)`,
          outlinedHoverBorder: `var(--joy-palette-neutral-300)`,
          outlinedActiveBg: `var(--joy-palette-neutral-200)`,
          outlinedDisabledColor: `var(--joy-palette-neutral-300)`,
          outlinedDisabledBorder: `var(--joy-palette-neutral-100)`,

          softColor: `var(--joy-palette-neutral-800)`,
          softBg: `var(--joy-palette-neutral-100)`,
          softHoverColor: `var(--joy-palette-neutral-900)`,
          softHoverBg: `var(--joy-palette-neutral-200)`,
          softActiveBg: `var(--joy-palette-neutral-300)`,
          softDisabledColor: `var(--joy-palette-neutral-300)`,
          softDisabledBg: `var(--joy-palette-neutral-50)`,
          solidColor: `var(--joy-palette-common-white)`,
          solidBg: `var(--joy-palette-neutral-600)`,
          solidHoverBg: `var(--joy-palette-neutral-700)`,
          solidActiveBg: `var(--joy-palette-neutral-800)`,
          solidDisabledColor: `var(--joy-palette-neutral-300)`,
          solidDisabledBg: `var(--joy-palette-neutral-50)`,
        },
        common: {
          white: '#FFF',
          black: '#09090D',
        },
        text: {
          secondary: 'var(--joy-palette-neutral-600)',
          tertiary: 'var(--joy-palette-neutral-500)',
        },
        background: {
          body: 'var(--joy-palette-common-white)',
          tooltip: 'var(--joy-palette-neutral-800)',
          backdrop: 'rgba(255 255 255 / 0.5)',
        },
      },
    },
    dark: {
      palette: {
        neutral: {
          ...neutral,
          plainColor: `var(--joy-palette-neutral-200)`,
          plainHoverColor: `var(--joy-palette-neutral-50)`,
          plainHoverBg: `var(--joy-palette-neutral-800)`,
          plainActiveBg: `var(--joy-palette-neutral-700)`,
          plainDisabledColor: `var(--joy-palette-neutral-700)`,

          outlinedColor: `var(--joy-palette-neutral-200)`,
          outlinedBorder: `var(--joy-palette-neutral-800)`,
          outlinedHoverColor: `var(--joy-palette-neutral-50)`,
          outlinedHoverBg: `var(--joy-palette-neutral-800)`,
          outlinedHoverBorder: `var(--joy-palette-neutral-700)`,
          outlinedActiveBg: `var(--joy-palette-neutral-800)`,
          outlinedDisabledColor: `var(--joy-palette-neutral-800)`,
          outlinedDisabledBorder: `var(--joy-palette-neutral-800)`,

          softColor: `var(--joy-palette-neutral-200)`,
          softBg: `var(--joy-palette-neutral-800)`,
          softHoverColor: `var(--joy-palette-neutral-50)`,
          softHoverBg: `var(--joy-palette-neutral-700)`,
          softActiveBg: `var(--joy-palette-neutral-600)`,
          softDisabledColor: `var(--joy-palette-neutral-700)`,
          softDisabledBg: `var(--joy-palette-neutral-900)`,

          solidColor: `var(--joy-palette-common-white)`,
          solidBg: `var(--joy-palette-neutral-600)`,
          solidHoverBg: `var(--joy-palette-neutral-700)`,
          solidActiveBg: `var(--joy-palette-neutral-800)`,
          solidDisabledColor: `var(--joy-palette-neutral-700)`,
          solidDisabledBg: `var(--joy-palette-neutral-900)`,
        },
        common: {
          white: '#FFF',
          black: '#09090D',
        },
        background: {
          body: 'var(--joy-palette-neutral-900)',
          surface: 'var(--joy-palette-common-black)',
          popup: 'var(--joy-palette-neutral-900)',
          level1: 'var(--joy-palette-neutral-800)',
          level2: 'var(--joy-palette-neutral-700)',
          level3: 'var(--joy-palette-neutral-600)',
        },
      },
    },
  },
});
Danger
const danger = {
  50: '#FFF8F6',
  100: '#FFE9E8',
  200: '#FFC7C5',
  300: '#FF9192',
  400: '#FA5255',
  500: '#D3232F',
  600: '#A10E25',
  700: '#77061B',
  800: '#580013',
  900: '#39000D',
};

extendTheme({
  colorSchemes: {
    light: {
      palette: {
        danger: {
          ...danger,
          plainColor: `var(--joy-palette-danger-600)`,
          plainHoverBg: `var(--joy-palette-danger-100)`,
          plainActiveBg: `var(--joy-palette-danger-200)`,
          plainDisabledColor: `var(--joy-palette-danger-200)`,

          outlinedColor: `var(--joy-palette-danger-500)`,
          outlinedBorder: `var(--joy-palette-danger-200)`,
          outlinedHoverBg: `var(--joy-palette-danger-100)`,
          outlinedHoverBorder: `var(--joy-palette-danger-300)`,
          outlinedActiveBg: `var(--joy-palette-danger-200)`,
          outlinedDisabledColor: `var(--joy-palette-danger-100)`,
          outlinedDisabledBorder: `var(--joy-palette-danger-100)`,

          softColor: `var(--joy-palette-danger-600)`,
          softBg: `var(--joy-palette-danger-100)`,
          softHoverBg: `var(--joy-palette-danger-200)`,
          softActiveBg: `var(--joy-palette-danger-300)`,
          softDisabledColor: `var(--joy-palette-danger-300)`,
          softDisabledBg: `var(--joy-palette-danger}-)50`,

          solidColor: '#fff',
          solidBg: `var(--joy-palette-danger-500)`,
          solidHoverBg: `var(--joy-palette-danger-600)`,
          solidActiveBg: `var(--joy-palette-danger-700)`,
          solidDisabledColor: `#fff`,
          solidDisabledBg: `var(--joy-palette-danger-200)`,
        },
      },
    },
    dark: {
      palette: {
        danger: {
          ...danger,
          plainColor: `var(--joy-palette-danger-300)`,
          plainHoverBg: `var(--joy-palette-danger-800)`,
          plainActiveBg: `var(--joy-palette-danger-700)`,
          plainDisabledColor: `var(--joy-palette-danger-800)`,

          outlinedColor: `var(--joy-palette-danger-200)`,
          outlinedBorder: `var(--joy-palette-danger-700)`,
          outlinedHoverBg: `var(--joy-palette-danger-800)`,
          outlinedHoverBorder: `var(--joy-palette-danger-600)`,
          outlinedActiveBg: `var(--joy-palette-danger-900)`,
          outlinedDisabledColor: `var(--joy-palette-danger-800)`,
          outlinedDisabledBorder: `var(--joy-palette-danger-800)`,

          softColor: `var(--joy-palette-danger-200)`,
          softBg: `var(--joy-palette-danger-900)`,
          softHoverBg: `var(--joy-palette-danger-800)`,
          softActiveBg: `var(--joy-palette-danger-700)`,
          softDisabledColor: `var(--joy-palette-danger-800)`,
          softDisabledBg: `var(--joy-palette-danger-900)`,

          solidColor: `#fff`,
          solidBg: `var(--joy-palette-danger-600)`,
          solidHoverBg: `var(--joy-palette-danger-700)`,
          solidActiveBg: `var(--joy-palette-danger-800)`,
          solidDisabledColor: `var(--joy-palette-danger-700)`,
          solidDisabledBg: `var(--joy-palette-danger-900)`,
        },
      },
    },
  },
});
Success
const success = {
  50: '#F3FEF5',
  100: '#D7F5DD',
  200: '#77EC95',
  300: '#4CC76E',
  400: '#2CA24D',
  500: '#1A7D36',
  600: '#0F5D26',
  700: '#034318',
  800: '#002F0F',
  900: '#001D09',
};

extendTheme({
  colorSchemes: {
    light: {
      palette: {
        success: {
          ...success,
          plainColor: `var(--joy-palette-success-600)`,
          plainHoverBg: `var(--joy-palette-success-100)`,
          plainActiveBg: `var(--joy-palette-success-200)`,
          plainDisabledColor: `var(--joy-palette-success-200)`,

          outlinedColor: `var(--joy-palette-success-500)`,
          outlinedBorder: `var(--joy-palette-success-200)`,
          outlinedHoverBg: `var(--joy-palette-success-100)`,
          outlinedHoverBorder: `var(--joy-palette-success-300)`,
          outlinedActiveBg: `var(--joy-palette-success-200)`,
          outlinedDisabledColor: `var(--joy-palette-success-100)`,
          outlinedDisabledBorder: `var(--joy-palette-success-100)`,

          softColor: `var(--joy-palette-success-600)`,
          softBg: `var(--joy-palette-success-100)`,
          softHoverBg: `var(--joy-palette-success-200)`,
          softActiveBg: `var(--joy-palette-success-300)`,
          softDisabledColor: `var(--joy-palette-success-300)`,
          softDisabledBg: `var(--joy-palette-success}-)50`,

          solidColor: '#fff',
          solidBg: `var(--joy-palette-success-500)`,
          solidHoverBg: `var(--joy-palette-success-600)`,
          solidActiveBg: `var(--joy-palette-success-700)`,
          solidDisabledColor: `#fff`,
          solidDisabledBg: `var(--joy-palette-success-200)`,
        },
      },
    },
    dark: {
      palette: {
        success: {
          ...success,
          plainColor: `var(--joy-palette-success-300)`,
          plainHoverBg: `var(--joy-palette-success-800)`,
          plainActiveBg: `var(--joy-palette-success-700)`,
          plainDisabledColor: `var(--joy-palette-success-800)`,

          outlinedColor: `var(--joy-palette-success-200)`,
          outlinedBorder: `var(--joy-palette-success-700)`,
          outlinedHoverBg: `var(--joy-palette-success-800)`,
          outlinedHoverBorder: `var(--joy-palette-success-600)`,
          outlinedActiveBg: `var(--joy-palette-success-900)`,
          outlinedDisabledColor: `var(--joy-palette-success-800)`,
          outlinedDisabledBorder: `var(--joy-palette-success-800)`,

          softColor: `var(--joy-palette-success-200)`,
          softBg: `var(--joy-palette-success-900)`,
          softHoverBg: `var(--joy-palette-success-800)`,
          softActiveBg: `var(--joy-palette-success-700)`,
          softDisabledColor: `var(--joy-palette-success-800)`,
          softDisabledBg: `var(--joy-palette-success-900)`,

          solidColor: '#fff',
          solidBg: `var(--joy-palette-success-600)`,
          solidHoverBg: `var(--joy-palette-success-700)`,
          solidActiveBg: `var(--joy-palette-success-800)`,
          solidDisabledColor: `var(--joy-palette-success-700)`,
          solidDisabledBg: `var(--joy-palette-success-900)`,
        },
      },
    },
  },
});
Warning
const warning = {
  50: '#FFF8C5',
  100: '#FAE17D',
  200: '#EAC54F',
  300: '#D4A72C',
  400: '#BF8700',
  500: '#9A6700',
  600: '#7D4E00',
  700: '#633C01',
  800: '#4D2D00',
  900: '#3B2300',
};

extendTheme({
  colorSchemes: {
    light: {
      palette: {
        warning: {
          ...warning,
          plainColor: `var(--joy-palette-warning-800)`,
          plainHoverBg: `var(--joy-palette-warning-50)`,
          plainActiveBg: `var(--joy-palette-warning-200)`,
          plainDisabledColor: `var(--joy-palette-warning-200)`,

          outlinedColor: `var(--joy-palette-warning-800)`,
          outlinedBorder: `var(--joy-palette-warning-200)`,
          outlinedHoverBg: `var(--joy-palette-warning-50)`,
          outlinedHoverBorder: `var(--joy-palette-warning-300)`,
          outlinedActiveBg: `var(--joy-palette-warning-200)`,
          outlinedDisabledColor: `var(--joy-palette-warning-100)`,
          outlinedDisabledBorder: `var(--joy-palette-warning-100)`,

          softColor: `var(--joy-palette-warning-800)`,
          softBg: `var(--joy-palette-warning-50)`,
          softHoverBg: `var(--joy-palette-warning-100)`,
          softActiveBg: `var(--joy-palette-warning-200)`,
          softDisabledColor: `var(--joy-palette-warning-200)`,
          softDisabledBg: `var(--joy-palette-warning-50)`,

          solidColor: `var(--joy-palette-warning-800)`,
          solidBg: `var(--joy-palette-warning-200)`,
          solidHoverBg: `var(--joy-palette-warning-300)`,
          solidActiveBg: `var(--joy-palette-warning-400)`,
          solidDisabledColor: `var(--joy-palette-warning-200)`,
          solidDisabledBg: `var(--joy-palette-warning-50)`,
        },
      },
    },
    dark: {
      palette: {
        warning: {
          ...warning,
          plainColor: `var(--joy-palette-warning-300)`,
          plainHoverBg: `var(--joy-palette-warning-800)`,
          plainActiveBg: `var(--joy-palette-warning-700)`,
          plainDisabledColor: `var(--joy-palette-warning-800)`,

          outlinedColor: `var(--joy-palette-warning-200)`,
          outlinedBorder: `var(--joy-palette-warning-700)`,
          outlinedHoverBg: `var(--joy-palette-warning-800)`,
          outlinedHoverBorder: `var(--joy-palette-warning-600)`,
          outlinedActiveBg: `var(--joy-palette-warning-900)`,
          outlinedDisabledColor: `var(--joy-palette-warning-800)`,
          outlinedDisabledBorder: `var(--joy-palette-warning-800)`,

          softColor: `var(--joy-palette-warning-200)`,
          softBg: `var(--joy-palette-warning-900)`,
          softHoverBg: `var(--joy-palette-warning-800)`,
          softActiveBg: `var(--joy-palette-warning-700)`,
          softDisabledColor: `var(--joy-palette-warning-800)`,
          softDisabledBg: `var(--joy-palette-warning-900)`,

          solidColor: `var(--joy-palette-common-black)`,
          solidBg: `var(--joy-palette-warning-300)`,
          solidHoverBg: `var(--joy-palette-warning-400)`,
          solidActiveBg: `var(--joy-palette-warning-500)`,
          solidDisabledColor: `var(--joy-palette-warning-700)`,
          solidDisabledBg: `var(--joy-palette-warning-900)`,
        },
      },
    },
  },
});

Font family

The default theme typeface has been changed to Inter. Follow the installation guide to install it.

To keep the old font family, add the following to your theme:

extendTheme({
  fontFamily: {
    display: '"Public Sans", var(--joy-fontFamily-fallback)',
    body: '"Public Sans", var(--joy-fontFamily-fallback)',
  },
});

Font size

The font size scale has been reduced to:

 {
-  xl7: '4.5rem',
-  xl6: '3.75rem',
-  xl5: '3rem',
   xl4: '2.25rem',
   xl3: '1.875rem',
   xl2: '1.5rem',
   xl: '1.25rem',
   lg: '1.125rem',
   md: '1rem',
   sm: '0.875rem',
   xs: '0.75rem',
-  xs2: '0.625rem',
-  xs3: '0.5rem',
 }

To keep the old font size scale, add the following to your theme:

extendTheme({
  fontSize: {
    xl7: '4.5rem',
    xl6: '3.75rem',
    xl5: '3rem',
    xs2: '0.625rem',
    xs3: '0.5rem',
  },
});

TypeScript

If working with TypeScript, add the old font size scale to the theme's type via module augmentation:

// You can put this to any file that's included in your tsconfig
declare module '@mui/joy/styles' {
  interface FontSizeOverrides {
    xl7: true;
    xl6: true;
    xl5: true;
    xs2: true;
    xs3: true;
  }
}

Font weight

The font weight scale has been reduced to:

 {
-  xs: 200,
   sm: 300,
   md: 500,
   lg: 600,
   xl: 700,
-  xl2: 800,
-  xl3: 900,
 }

To keep the old font weight scale, add the following to your theme:

extendTheme({
  fontWeight: {
    xs: 200,
    xl2: 800,
    xl3: 900,
  },
});

TypeScript

If working with TypeScript, add the old font weight scale to the theme's type via module augmentation:

// You can put this to any file that's included in your tsconfig
declare module '@mui/joy/styles' {
  interface FontWeightOverrides {
    xs: true;
    xl2: true;
    xl3: true;
  }
}

Line height

The font size scale has been changed to:

 {
-  sm: 1.25,
-  md: 1.5,
-  lg: 1.7,
+  xs: 1.33334, // largest font sizes for h1, h2
+  sm: 1.42858, // normal font sizes
+  md: 1.5, // normal font sizes
+  lg: 1.55556, // large font sizes for components
+  xl: 1.66667, // smallest font sizes
 }

Letter spacing

The letter spacing scale has been removed. To add it back, add the following to your theme:

extendTheme({
  letterSpacing: {
    sm: '-0.01em',
    md: '0.083em',
    lg: '0.125em',
  },
});

TypeScript

If working with TypeScript, add the old letter spacing scale to the theme's type via module augmentation:

// You can put this to any file that's included in your tsconfig
declare module '@mui/joy/styles' {
  interface ThemeScales {
    letterSpacing: {
      sm: string;
      md: string;
      lg: string;
    };
  }
}

Level

The default typography level scale (theme.typography.*) has been restructured to:

  h1
  h2
  h3
  h4
+ title-lg
+ title-md
+ title-sm
+ body-lg
+ body-md
+ body-sm
+ body-xs
- display1
- display2
- h5 // recommend to use `title-lg` instead
- h6 // recommend to use `title-md` instead
- body1 // recommend to use `body-md` instead
- body2 // recommend to use `body-sm` instead
- body3 // recommend to use `body-xs` instead
- body4
- body5

The reason behind this restructure is to make the levels more consistent and easier to use. The h1 through h4 levels are intended to be used for page headings, while the title-* and body-* levels are intended to be used as page paragraphs and as component texts.

The title-* and body-* levels are designed to be composable which align perfectly with each size of the SvgIcon component:

title-lg: Title of the component

body-md: This is the description of the component that contain some information of it.

title-md: Title of the component

body-md: This is the description of the component that contain some information of it.

body-sm: Metadata, for example a date.

title-sm: Title of the component

body-sm: This is the description of the component that contain some information of it.

body-xs: Metadata, for example a date.

Shadow

The shadow scale remains the same but all values have been changed.

To keep the old shadow scale, add the following to your theme:

extendTheme({
  shadow: {
    xs: `var(--joy-shadowRing, 0 0 #000),
        0 1px 2px 0 rgba(var(--joy-shadowChannel, 187 187 187) / 0.12)`,
    sm: `var(--joy-shadowRing, 0 0 #000),
        0.3px 0.8px 1.1px rgba(var(--joy-shadowChannel, 187 187 187) / 0.11),
        0.5px 1.3px 1.8px -0.6px rgba(var(--joy-shadowChannel, 187 187 187) / 0.18),
        1.1px 2.7px 3.8px -1.2px rgba(var(--joy-shadowChannel, 187 187 187) / 0.26)`,
    md: `var(--joy-shadowRing, 0 0 #000),
        0.3px 0.8px 1.1px rgba(var(--joy-shadowChannel, 187 187 187) / 0.12),
        1.1px 2.8px 3.9px -0.4px rgba(var(--joy-shadowChannel, 187 187 187) / 0.17),
        2.4px 6.1px 8.6px -0.8px rgba(var(--joy-shadowChannel, 187 187 187) / 0.23),
        5.3px 13.3px 18.8px -1.2px rgba(var(--joy-shadowChannel, 187 187 187) / 0.29)`,
    lg: `var(--joy-shadowRing, 0 0 #000),
        0.3px 0.8px 1.1px rgba(var(--joy-shadowChannel, 187 187 187) / 0.11),
        1.8px 4.5px 6.4px -0.2px rgba(var(--joy-shadowChannel, 187 187 187) / 0.13),
        3.2px 7.9px 11.2px -0.4px rgba(var(--joy-shadowChannel, 187 187 187) / 0.16),
        4.8px 12px 17px -0.5px rgba(var(--joy-shadowChannel, 187 187 187) / 0.19),
        7px 17.5px 24.7px -0.7px rgba(var(--joy-shadowChannel, 187 187 187) / 0.21)`,
    xl: `var(--joy-shadowRing, 0 0 #000),
        0.3px 0.8px 1.1px rgba(var(--joy-shadowChannel, 187 187 187) / 0.11), 
        1.8px 4.5px 6.4px -0.2px rgba(var(--joy-shadowChannel, 187 187 187) / 0.13), 
        3.2px 7.9px 11.2px -0.4px rgba(var(--joy-shadowChannel, 187 187 187) / 0.16), 
        4.8px 12px 17px -0.5px rgba(var(--joy-shadowChannel, 187 187 187) / 0.19), 
        7px 17.5px 24.7px -0.7px rgba(var(--joy-shadowChannel, 187 187 187) / 0.21), 
        10.2px 25.5px 36px -0.9px rgba(var(--joy-shadowChannel, 187 187 187) / 0.24), 
        14.8px 36.8px 52.1px -1.1px rgba(var(--joy-shadowChannel, 187 187 187) / 0.27), 21px 52.3px 74px -1.2px rgba(var(--joy-shadowChannel, 187 187 187) / 0.29)`,
  },
});

Components

Alert

The default variant has been changed to outlined and the default color has been changed to neutral.

To keep the old default variant and color, add the following to your theme:

extendTheme({
  components: {
    JoyAlert: {
      defaultProps: {
        variant: 'soft',
        color: 'primary',
      },
    },
  },
});

Autocomplete

The variant and color are now the same for input and listbox slots.

If you want to use a different variant for a specific slot, use slotProps. In the following example, the listbox slot uses the plain variant:

<Autocomplete
  variant="plain"
  slotProps={{
    listbox: {
      variant: 'plain',
    }
  }}
>

Chip

The default variant has been changed to soft and the default color has been changed to neutral.

To keep the old default variant and color, add the following to your theme:

extendTheme({
  components: {
    JoyChip: {
      defaultProps: {
        variant: 'solid',
        color: 'primary',
      },
    },
  },
});

ChipDelete

The default variant has been changed to plain and the default color has been changed to neutral.

To keep the old default variant and color, add the following to your theme:

extendTheme({
  components: {
    JoyChipDelete: {
      defaultProps: {
        variant: 'solid',
        color: 'primary',
      },
    },
  },
});

IconButton

The default variant has been changed to plain and the default color has been changed to neutral.

To keep the old default variant and color, add the following to your theme:

extendTheme({
  components: {
    JoyIconButton: {
      defaultProps: {
        variant: 'soft',
        color: 'primary',
      },
    },
  },
});

Tabs

The Tabs component has been redesigned following feedback we've received on this GitHub issue.

First tab panel
Press Enter to start editing

To keep the old Tabs design, add the following to your theme:

extendTheme({
  components: {
    JoyTabList: {
      defaultProps: {
        variant: 'soft',
        disableUnderline: true,
      },
      styleOverrides: {
        root: {
          gap: '0.25rem',
          padding: '0.25rem',
          '--List-padding': '0.25rem',
          borderRadius: 'var(--joy-radius-xl)',
          '--List-radius': 'var(--joy-radius-xl)',
        },
      },
    },
    JoyTab: {
      defaultProps: {
        disableIndicator: true,
      },
      styleOverrides: {
        root: {
          '&[aria-selected="true"]': {
            boxShadow: 'var(--joy-shadow-sm)',
            backgroundColor: 'var(--joy-palette-background-surface)',
          },
        },
      },
    },
  },
});

Select

The variant and color are now the same for button and listbox slots.

If you want to use a different variant for a specific slot, use slotProps. In the following example, the listbox slot uses the plain variant:

<Select
  variant="plain"
  slotProps={{
    listbox: {
      variant: 'plain',
    }
  }}
>