Skip to content

CSS theme variables - Usage

Learn how to use the experimental APIs to adopt CSS theme variables.

Getting started

Experimental_CssVarsProvider is a provider that generates CSS theme variables and attaches a reference to the theme object (a React context).

import { Experimental_CssVarsProvider as CssVarsProvider } from '@mui/material/styles';

function App() {
  return <CssVarsProvider>...</CssVarsProvider>;

Once the App renders on the screen, you will see the CSS theme variables in the html :root stylesheet. The variables are flattened and prefixed with --mui by default:

/* generated global stylesheet */
:root {
  --mui-palette-primary-main: #1976d2;
  --mui-palette-primary-light: #42a5f5;
  --mui-palette-primary-dark: #1565c0;
  --mui-palette-primary-contrastText: #fff;
  /* ...other variables */

Toggle between light and dark mode

The useColorScheme hook lets you read and update the user-selected mode:

import {
  Experimental_CssVarsProvider as CssVarsProvider,
} from '@mui/material/styles';

// ModeSwitcher is an example interface for toggling between modes.
// Material UI does not provide the toggle interface—you have to build it yourself.
const ModeSwitcher = () => {
  const { mode, setMode } = useColorScheme();
  const [mounted, setMounted] = React.useState(false);

  React.useEffect(() => {
  }, []);

  if (!mounted) {
    // for server-side rendering
    // learn more at
    return null;

  return (
      onClick={() => {
        if (mode === 'light') {
        } else {
      {mode === 'light' ? 'Dark' : 'Light'}

function App() {
  return (
      <ModeSwitcher />

Using theme variables

  • theme.vars (recommended): an object that refers to the CSS theme variables.

    const Button = styled('button')(({ theme }) => ({
      backgroundColor: theme.vars.palette.primary.main, // var(--mui-palette-primary-main)
      color: theme.vars.palette.primary.contrastText, // var(--mui-palette-primary-contrastText)

    For TypeScript, the typings are not enabled by default. Follow the TypeScript setup to enable the typings.

  • Native CSS: if you can't access the theme object, e.g. in a pure CSS file, you can use var() directly:

    /* external-scope.css */
    .external-section {
      background-color: var(--mui-palette-grey-50);

Server-side rendering

Place getInitColorSchemeScript() before the <Main /> tag to prevent the dark-mode SSR flickering during the hydration phase.


Add the following code to the custom pages/_document.js file:

import Document, { Html, Head, Main, NextScript } from 'next/document';
import { getInitColorSchemeScript } from '@mui/material/styles';

export default class MyDocument extends Document {
  render() {
    return (
          <Main />
          <NextScript />


Add the following code to the custom gatsby-ssr.js file:

import React from 'react';
import { getInitColorSchemeScript } from '@mui/material/styles';

export function onRenderBody({ setPreBodyComponents }) {


The theme variables type is not enabled by default. You need to import the module augmentation to enable the typings:

// The import can be in any file that is included in your `tsconfig.json`
import type {} from '@mui/material/themeCssVarsAugmentation';
import { styled } from '@mui/material/styles';

const StyledComponent = styled('button')(({ theme }) => ({
  // ✅ typed-safe
  color: theme.vars.palette.primary.main,