Skip to content

Dark mode

Material UI comes with two palette modes: light (the default) and dark.

Dark mode by default

You can make your application use the dark theme as the default—regardless of the user's preference—by adding mode: 'dark' to the createTheme helper:

<span class="token keyword">import</span> <span class="token punctuation">{</span> ThemeProvider<span class="token punctuation">,</span> createTheme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/styles'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> CssBaseline <span class="token keyword">from</span> <span class="token string">'@mui/material/CssBaseline'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> darkTheme <span class="token operator">=</span> <span class="token function">createTheme</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  <span class="token literal-property property">palette</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token literal-property property">mode</span><span class="token operator">:</span> <span class="token string">'dark'</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>darkTheme<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CssBaseline</span></span> <span class="token punctuation">/></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>main</span><span class="token punctuation">></span></span>This app is using the dark mode<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>main</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ThemeProvider</span></span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> App<span class="token punctuation">;</span>

Adding mode: 'dark' to the createTheme helper modifies several palette values, as shown in the following demo:

Typography

palette.text.primary

#fff

palette.text.secondary

rgba(255, 255, 255, 0.7)

palette.text.disabled

rgba(255, 255, 255, 0.5)

Buttons

palette.action.active

#fff

palette.action.hover

rgba(255, 255, 255, 0.08)

palette.action.selected

rgba(255, 255, 255, 0.16)

palette.action.disabled

rgba(255, 255, 255, 0.3)

palette.action.disabledBackground

rgba(255, 255, 255, 0.12)

Background

palette.background.default

#121212

palette.background.paper

#121212

Divider

palette.divider

rgba(255, 255, 255, 0.12)

Typography

palette.text.primary

rgba(0, 0, 0, 0.87)

palette.text.secondary

rgba(0, 0, 0, 0.6)

palette.text.disabled

rgba(0, 0, 0, 0.38)

Buttons

palette.action.active

rgba(0, 0, 0, 0.54)

palette.action.hover

rgba(0, 0, 0, 0.04)

palette.action.selected

rgba(0, 0, 0, 0.08)

palette.action.disabled

rgba(0, 0, 0, 0.26)

palette.action.disabledBackground

rgba(0, 0, 0, 0.12)

Background

palette.background.default

#fff

palette.background.paper

#fff

Divider

palette.divider

rgba(0, 0, 0, 0.12)

Adding <CssBaseline /> inside of the <ThemeProvider> component will also enable dark mode for the app's background.

Dark mode with a custom palette

To use custom palettes for light and dark modes, you can create a function that will return the correct palette depending on the selected mode, as shown here:

<span class="token keyword">const</span> <span class="token function-variable function">getDesignTokens</span> <span class="token operator">=</span> <span class="token punctuation">(</span>mode<span class="token operator">:</span> PaletteMode<span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
  palette<span class="token operator">:</span> <span class="token punctuation">{</span>
    mode<span class="token punctuation">,</span>
    <span class="token operator">...</span><span class="token punctuation">(</span>mode <span class="token operator">===</span> <span class="token string">'light'</span>
      <span class="token operator">?</span> <span class="token punctuation">{</span>
          <span class="token comment">// palette values for light mode</span>
          primary<span class="token operator">:</span> amber<span class="token punctuation">,</span>
          divider<span class="token operator">:</span> amber<span class="token punctuation">[</span><span class="token number">200</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
          text<span class="token operator">:</span> <span class="token punctuation">{</span>
            primary<span class="token operator">:</span> grey<span class="token punctuation">[</span><span class="token number">900</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
            secondary<span class="token operator">:</span> grey<span class="token punctuation">[</span><span class="token number">800</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
          <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span>
      <span class="token operator">:</span> <span class="token punctuation">{</span>
          <span class="token comment">// palette values for dark mode</span>
          primary<span class="token operator">:</span> deepOrange<span class="token punctuation">,</span>
          divider<span class="token operator">:</span> deepOrange<span class="token punctuation">[</span><span class="token number">700</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
          background<span class="token operator">:</span> <span class="token punctuation">{</span>
            <span class="token keyword">default</span><span class="token operator">:</span> deepOrange<span class="token punctuation">[</span><span class="token number">900</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
            paper<span class="token operator">:</span> deepOrange<span class="token punctuation">[</span><span class="token number">900</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
          <span class="token punctuation">}</span><span class="token punctuation">,</span>
          text<span class="token operator">:</span> <span class="token punctuation">{</span>
            primary<span class="token operator">:</span> <span class="token string">'#fff'</span><span class="token punctuation">,</span>
            secondary<span class="token operator">:</span> grey<span class="token punctuation">[</span><span class="token number">500</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
          <span class="token punctuation">}</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

You can see on the example that there are different colors used based on whether the mode is light or dark. The next step is to use this function when creating the theme.

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>mode<span class="token punctuation">,</span> setMode<span class="token punctuation">]</span> <span class="token operator">=</span> React<span class="token punctuation">.</span>useState<span class="token operator">&lt;</span>PaletteMode<span class="token operator">></span><span class="token punctuation">(</span><span class="token string">'light'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> colorMode <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">useMemo</span><span class="token punctuation">(</span>
    <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">(</span><span class="token punctuation">{</span>
      <span class="token comment">// The dark mode switch would invoke this method</span>
      <span class="token function-variable function">toggleColorMode</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
        <span class="token function">setMode</span><span class="token punctuation">(</span><span class="token punctuation">(</span>prevMode<span class="token operator">:</span> PaletteMode<span class="token punctuation">)</span> <span class="token operator">=></span>
          prevMode <span class="token operator">===</span> <span class="token string">'light'</span> <span class="token operator">?</span> <span class="token string">'dark'</span> <span class="token operator">:</span> <span class="token string">'light'</span><span class="token punctuation">,</span>
        <span class="token punctuation">)</span><span class="token punctuation">;</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// Update the theme only if the mode changes</span>
  <span class="token keyword">const</span> theme <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">useMemo</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">createTheme</span><span class="token punctuation">(</span><span class="token function">getDesignTokens</span><span class="token punctuation">(</span>mode<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>mode<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ColorModeContext.Provider</span></span> <span class="token attr-name">value</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>colorMode<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>theme<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Page</span></span> <span class="token punctuation">/></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ThemeProvider</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ColorModeContext.Provider</span></span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Here is a fully working example:

This is a dark mode theme with custom palette

Toggling color mode

To give your users a way to toggle between modes, you can add React's context to a button's onClick event, as shown in the following demo:

light mode

System preference

Users might have a preference for light or dark mode that they've set through their operating system—either systemwide, or for a single user agent.

You can make use of this preference with the useMediaQuery hook and the prefers-color-scheme media query.

The following demo shows how to enable dark mode automatically by checking for the user's preference in their OS or browser settings:

<span class="token keyword">import</span> <span class="token operator">*</span> <span class="token keyword">as</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> useMediaQuery <span class="token keyword">from</span> <span class="token string">'@mui/material/useMediaQuery'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> createTheme<span class="token punctuation">,</span> ThemeProvider <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/styles'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> CssBaseline <span class="token keyword">from</span> <span class="token string">'@mui/material/CssBaseline'</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> prefersDarkMode <span class="token operator">=</span> <span class="token function">useMediaQuery</span><span class="token punctuation">(</span><span class="token string">'(prefers-color-scheme: dark)'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">const</span> theme <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">useMemo</span><span class="token punctuation">(</span>
    <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span>
      <span class="token function">createTheme</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
        <span class="token literal-property property">palette</span><span class="token operator">:</span> <span class="token punctuation">{</span>
          <span class="token literal-property property">mode</span><span class="token operator">:</span> prefersDarkMode <span class="token operator">?</span> <span class="token string">'dark'</span> <span class="token operator">:</span> <span class="token string">'light'</span><span class="token punctuation">,</span>
        <span class="token punctuation">}</span><span class="token punctuation">,</span>
      <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">[</span>prefersDarkMode<span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">ThemeProvider</span></span> <span class="token attr-name">theme</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>theme<span class="token punctuation">}</span></span><span class="token punctuation">></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CssBaseline</span></span> <span class="token punctuation">/></span></span>
      <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Routes</span></span> <span class="token punctuation">/></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ThemeProvider</span></span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>