Skip to content

Using Joy UI and Material UI together

Learn how to use Joy UI and Material UI together in the same project.

Introduction

There are two main use cases for using them together:

  1. Your existing project already uses Material UI but you're willing to explore the new components and style Joy UI offers.
  2. You've started your project with Joy UI but you find a key component you need is missing.

Additionally, keep these in mind when using them together:

  • Both of them use MUI System as their style engine, which uses React context for theming.
  • Theme scoping must be done on one of the libraries.

Prerequisite

  • Have @mui/material and @mui/joy installed in your project.
  • The version of both libraries must be v5.12.0 or higher.

Set up the providers

Render Material UI's CssVarsProvider inside Joy UI's provider and use THEME_ID to separate the themes from each other.

<span class="token keyword">import</span> <span class="token punctuation">{</span>
  experimental_extendTheme <span class="token keyword">as</span> materialExtendTheme<span class="token punctuation">,</span>
  Experimental_CssVarsProvider <span class="token keyword">as</span> MaterialCssVarsProvider<span class="token punctuation">,</span>
  <span class="token constant">THEME_ID</span> <span class="token keyword">as</span> <span class="token constant">MATERIAL_THEME_ID</span><span class="token punctuation">,</span>
<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> <span class="token punctuation">{</span> CssVarsProvider <span class="token keyword">as</span> JoyCssVarsProvider <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/joy/styles'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> materialTheme <span class="token operator">=</span> <span class="token function">materialExtendTheme</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> <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">MaterialCssVarsProvider</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><span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">MATERIAL_THEME_ID</span><span class="token punctuation">]</span><span class="token operator">:</span> materialTheme <span class="token punctuation">}</span><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">JoyCssVarsProvider</span></span><span class="token punctuation">></span></span><span class="token operator">...</span>Material <span class="token constant">UI</span> and Joy <span class="token constant">UI</span> components<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">JoyCssVarsProvider</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">MaterialCssVarsProvider</span></span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

Sync the color mode

To sync the color mode between the providers, call setMode from both of the libraries:

<span class="token keyword">import</span> <span class="token punctuation">{</span> useColorScheme <span class="token keyword">as</span> useJoyColorScheme <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/joy/styles'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> useColorScheme <span class="token keyword">as</span> useMaterialColorScheme <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">const</span> <span class="token function-variable function">ModeToggle</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 keyword">const</span> <span class="token punctuation">{</span> mode<span class="token punctuation">,</span> <span class="token literal-property property">setMode</span><span class="token operator">:</span> setMaterialMode <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">useMaterialColorScheme</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> <span class="token literal-property property">setMode</span><span class="token operator">:</span> setJoyMode <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">useJoyColorScheme</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>mounted<span class="token punctuation">,</span> setMounted<span class="token punctuation">]</span> <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">useState</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  React<span class="token punctuation">.</span><span class="token function">useEffect</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 function">setMounted</span><span class="token punctuation">(</span><span class="token boolean">true</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 keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>mounted<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">// prevent server-side rendering mismatch</span>
    <span class="token comment">// because `mode` is undefined on the server.</span>
    <span class="token keyword">return</span> <span class="token keyword">null</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">IconButton</span></span>
      <span class="token attr-name">onClick</span><span class="token script language-javascript"><span class="token script-punctuation 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 function">setMode</span><span class="token punctuation">(</span>mode <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 operator">:</span> <span class="token string">'dark'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">setJoyMode</span><span class="token punctuation">(</span>mode <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 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>
    <span class="token punctuation">></span></span>
      <span class="token punctuation">{</span><span class="token comment">/** You can use `mode` from Joy UI or Material UI since they are synced **/</span><span class="token punctuation">}</span>
      <span class="token punctuation">{</span>mode <span class="token operator">===</span> <span class="token string">'dark'</span> <span class="token operator">?</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">DarkMode</span></span> <span class="token punctuation">/></span></span> <span class="token operator">:</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">LightMode</span></span> <span class="token punctuation">/></span></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">IconButton</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 punctuation">;</span>

Default mode

If you want to change the defaultMode, you have to specify the prop to both of the providers:

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">MaterialCssVarsProvider</span></span>
  <span class="token attr-name">defaultMode</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>system<span class="token punctuation">"</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><span class="token punctuation">{</span> <span class="token punctuation">[</span><span class="token constant">MATERIAL_THEME_ID</span><span class="token punctuation">]</span><span class="token operator">:</span> materialTheme <span class="token punctuation">}</span><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">JoyCssVarsProvider</span></span> <span class="token attr-name">defaultMode</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>system<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token operator">...</span>Material <span class="token constant">UI</span> and Joy <span class="token constant">UI</span> components
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">JoyCssVarsProvider</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">MaterialCssVarsProvider</span></span><span class="token punctuation">></span></span>

Caveat

Both libraries have the same class name prefix:

<span class="token keyword">import</span> MaterialTypography<span class="token punctuation">,</span> <span class="token punctuation">{</span>
  typographyClasses <span class="token keyword">as</span> muiTypographyClasses<span class="token punctuation">,</span>
<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/material/Typography'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> JoyTypography<span class="token punctuation">,</span> <span class="token punctuation">{</span>
  typographyClasses <span class="token keyword">as</span> joyTyographyClasses<span class="token punctuation">,</span>
<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@mui/joy/Typography'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> Stack <span class="token keyword">from</span> <span class="token string">'@mui/material/Stack'</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">Stack</span></span>
  <span class="token attr-name">sx</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token punctuation">{</span>
    <span class="token comment">// similar to `&amp; .${joyTyographyClasses.root}`</span>
    <span class="token punctuation">[</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">&amp; .</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>muiTypographyClasses<span class="token punctuation">.</span>root<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">]</span><span class="token operator">:</span> <span class="token punctuation">{</span>
      <span class="token literal-property property">color</span><span class="token operator">:</span> <span class="token string">'red'</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>
<span class="token punctuation">></span></span>
  <span class="token punctuation">{</span><span class="token comment">/* Both components are red. */</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">MaterialTypography</span></span><span class="token punctuation">></span></span>Red<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">MaterialTypography</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">JoyTypography</span></span><span class="token punctuation">></span></span>Red<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">JoyTypography</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">Stack</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span>

Joy UI and Material UI components have a different name for theming the components. For example, Joy UI's Button uses JoyButton whereas Material UI's Button uses MuiButton.