useDarkMode


Custom hook that returns the current state of the dark mode.

Usage

import { useDarkMode } from 'usehooks-ts'

export default function Component() {
  const { isDarkMode, toggle, enable, disable } = useDarkMode()

  return (
    <div>
      <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>
      <button onClick={toggle}>Toggle</button>
      <button onClick={enable}>Enable</button>
      <button onClick={disable}>Disable</button>
    </div>
  )
}

API

useDarkMode(options?): DarkModeReturn

Custom hook that returns the current state of the dark mode.

Parameters

NameTypeDescription
options?DarkModeOptionsThe initial value of the dark mode, default false.

Returns

DarkModeReturn

An object containing the dark mode's state and its controllers.

Type aliases

Ƭ DarkModeOptions: Object

The hook options.

Type declaration

NameTypeDescription
defaultValue?booleanThe initial value of the dark mode. Default ts false
initializeWithValue?booleanIf true (default), the hook will initialize reading localStorage. In SSR, you should set it to false, returning the defaultValue or false initially. Default ts true
localStorageKey?stringThe key to use in the local storage. Default ts 'usehooks-ts-dark-mode'

Ƭ DarkModeReturn: Object

The hook return type.

Type declaration

NameTypeDescription
disable() => voidFunction to disable the dark mode.
enable() => voidFunction to enable the dark mode.
isDarkModebooleanThe current state of the dark mode.
set(value: boolean) => voidFunction to set a specific value to the dark mode.
toggle() => voidFunction to toggle the dark mode.

Hook

import {
  useIsomorphicLayoutEffect,
  useLocalStorage,
  useMediaQuery,
} from 'usehooks-ts'

const COLOR_SCHEME_QUERY = '(prefers-color-scheme: dark)'
const LOCAL_STORAGE_KEY = 'usehooks-ts-dark-mode'

type DarkModeOptions = {
  defaultValue?: boolean
  localStorageKey?: string
  initializeWithValue?: boolean
}

type DarkModeReturn = {
  isDarkMode: boolean
  toggle: () => void
  enable: () => void
  disable: () => void
  set: (value: boolean) => void
}

export function useDarkMode(options: DarkModeOptions = {}): DarkModeReturn {
  const {
    defaultValue,
    localStorageKey = LOCAL_STORAGE_KEY,
    initializeWithValue = true,
  } = options

  const isDarkOS = useMediaQuery(COLOR_SCHEME_QUERY, {
    initializeWithValue,
    defaultValue,
  })
  const [isDarkMode, setDarkMode] = useLocalStorage<boolean>(
    localStorageKey,
    defaultValue ?? isDarkOS ?? false,
    { initializeWithValue },
  )

  // Update darkMode if os prefers changes
  useIsomorphicLayoutEffect(() => {
    if (isDarkOS !== isDarkMode) {
      setDarkMode(isDarkOS)
    }
  }, [isDarkOS])

  return {
    isDarkMode,
    toggle: () => {
      setDarkMode(prev => !prev)
    },
    enable: () => {
      setDarkMode(true)
    },
    disable: () => {
      setDarkMode(false)
    },
    set: value => {
      setDarkMode(value)
    },
  }
}