useDarkMode()

This React Hook offers you an interface to enable, disable, toggle and read the dark theme mode. The returned value (isDarkMode) is a boolean to let you be able to use with your logic.

It uses internally useLocalStorage() to persist the value and listens the OS color scheme preferences.

The Hook

1import { useLocalStorage, useMediaQuery, useUpdateEffect } from 'usehooks-ts'
2
3const COLOR_SCHEME_QUERY = '(prefers-color-scheme: dark)'
4
5interface UseDarkModeOutput {
6 isDarkMode: boolean
7 toggle: () => void
8 enable: () => void
9 disable: () => void
10}
11
12function useDarkMode(defaultValue?: boolean): UseDarkModeOutput {
13 const isDarkOS = useMediaQuery(COLOR_SCHEME_QUERY)
14 const [isDarkMode, setDarkMode] = useLocalStorage<boolean>(
15 'usehooks-ts-dark-mode',
16 defaultValue ?? isDarkOS ?? false,
17 )
18
19 // Update darkMode if os prefers changes
20 useUpdateEffect(() => {
21 setDarkMode(isDarkOS)
22 // eslint-disable-next-line react-hooks/exhaustive-deps
23 }, [isDarkOS])
24
25 return {
26 isDarkMode,
27 toggle: () => setDarkMode(prev => !prev),
28 enable: () => setDarkMode(true),
29 disable: () => setDarkMode(false),
30 }
31}
32
33export default useDarkMode

Usage

1import { useDarkMode } from 'usehooks-ts'
2
3export default function Component() {
4 const { isDarkMode, toggle, enable, disable } = useDarkMode()
5
6 return (
7 <div>
8 <p>Current theme: {isDarkMode ? 'dark' : 'light'}</p>
9 <button onClick={toggle}>Toggle</button>
10 <button onClick={enable}>Enable</button>
11 <button onClick={disable}>Disable</button>
12 </div>
13 )
14}

Edit on CodeSandbox

See a way to make this page better?
Edit there »