Dark mode

NextUI comes with two palette modes light (the default) and dark, as we mentioned before. you can make the theme dark by setting type: dark.

import { createTheme } from "@nextui-org/react"

const darkTheme = createTheme({
  type: 'dark',
  theme: {
    colors: {...}, // override dark theme colors
  }
});

For further information about createTheme, please refer to the typescript documentation.

Using next-themes

If you are using NextUI in conjuction with Next.js the best way to apply the dark mode is using the next-themes package.

NextUI automatically changes the theme when detects that next-themes changes the current theme.

Here is an example of how to use next-themes:

// 1. Import `createTheme`
import { createTheme, NextUIProvider } from "@nextui-org/react"
import { ThemeProvider as NextThemesProvider } from 'next-themes';

// 2. Call `createTheme` and pass your custom values
const lightTheme = createTheme({
  type: 'light',
  theme: {
    colors: {...}, // optional
  }
})

const darkTheme = createTheme({
  type: 'dark',
  theme: {
    colors: {...}, // optional
  }
})


// 3. Wrap NextUIProvider with NextThemesProvider
// _app.jsx // _app.tsx
<NextThemesProvider
    defaultTheme="system"
    attribute="class"
    value={{
      light: lightTheme.className,
      dark: darkTheme.className
    }}
  >
  <NextUIProvider>
    <App />
  </NextUIProvider>
</NextThemesProvider>


// 4. Use `next-themes` to change the theme
import { useTheme as useNextTheme } from 'next-themes'
import { Switch, useTheme } from '@nextui-org/react'

const App = () => {
  const { setTheme } = useNextTheme();
  const { isDark, type } = useTheme();

  return (
    <div>
      The current theme is: {type}
      <Switch
        checked={isDark}
        onChange={(e) => setTheme(e.target.checked ? 'dark' : 'light')}
      />
    </div>
  )
}

And that's it! 🎉

You have a no-flashing dark theme implementation for your Next.js app.

For more information on the next-themes check out the docs

For more information on the default colors, fonts, spaces, etc.. please refer to the default theme documentation.

Using use-dark-mode

If you are using NextUI in conjuction with plain React.js a good way to apply the dark mode is using the use-dark-mode hook.

Here is an example of how to use use-dark-mode:

// 1. Import `createTheme`
import { createTheme, NextUIProvider } from "@nextui-org/react"
import useDarkMode from 'use-dark-mode';

// 2. Call `createTheme` and pass your custom values
const lightTheme = createTheme({
  type: 'light',
  theme: {
    colors: {...},
  }
})

const darkTheme = createTheme({
  type: 'dark',
  theme: {
    colors: {...},
  }
})


// 3. Apply light or dark theme depending on useDarkMode value
// App.jsx entry point of your app


const darkMode = useDarkMode(false);

return (
  <NextUIProvider theme={darkMode.value ? darkTheme : lightTheme}>
    <App />
  </NextUIProvider>
)


// 4. Use `useDarkMode` to change the theme
import { Switch, useTheme } from '@nextui-org/react'
import useDarkMode from 'use-dark-mode';

const App = () => {
  const darkMode = useDarkMode(false);
  const { type, isDark } = useTheme();

  return (
    <div>
      The current theme is: {type}
      <Switch
        checked={darkMode.value}
        onChange={() => darkMode.toggle()}
      />
    </div>
  )
}

For more information about use-dark-mode check out the docs

Custom implementation

NextUI exposes a changeTheme method that you can use to change the theme but you have to be sure that you have created the passed theme before.

This method is also useful when you want to change the theme outside a React Component.

Here is an example of how to implement a custom dark mode:

// 1. Import `createTheme`
import { createTheme } from "@nextui-org/react"

// 2. Call `createTheme` and pass your custom values
const lightTheme = createTheme({
  type: 'light',
  theme: {
    colors: {...},
  }
})

const darkTheme = createTheme({
  type: 'dark',
  theme: {
    colors: {...},
  }
})


// 3. Apply light or dark theme depending on localStorage and `getDocumentTheme` value
// App.jsx entry point of your app
import React, { useEffect, useState } from 'react';
import { getDocumentTheme } from '@nextui-org/react'

const Main = () => {
  const [isDark, setIsDark] = useState(false);

  useEffect(() => {
    // you can use any storage
    let theme = window.localStorage.getItem('data-theme');
    setIsDark(theme === 'dark');

    const observer = new MutationObserver((mutation) => {
      let newTheme = getDocumentTheme(document?.documentElement);
      setIsDark(newTheme === 'dark');
    });

    // Observe the document theme changes
    observer.observe(document?.documentElement, {
      attributes: true,
      attributeFilter: ['data-theme', 'style']
    });

    return () => observer.disconnect();
  }, []);

  return (
    <NextUIProvider theme={isDark ? darkTheme : lightTheme}>
      <App />
    </NextUIProvider>
  )
}

// 4. Use `changeTheme` method to control theme changing
import { Switch, changeTheme, useTheme } from '@nextui-org/react'

const App = () => {
  const { type, isDark } = useTheme();

  const handleChange = () => {
    const nextTheme = isDark ? 'light' : 'dark';
    window.localStorage.setItem('data-theme', nextTheme); // you can use any storage
    changeTheme(nextTheme);
  }

  return (
    <div>
      The current theme is: {type}
      <Switch
        checked={isDark}
        onChange={handleChange}
      />
    </div>
  )
}

Note: This dark mode implementation is less recommended because it occurs only on the client side, which means that the theme can flash when the page is loaded.

gradient blue backgroundgradient violet background