30% offEnding soon
useDarkModeLoading saved progress…

useDarkMode

Build a hook that reports whether the user's operating system or browser currently prefers a dark color scheme. CSS can react to this setting with @media (prefers-color-scheme: dark); JavaScript gets the same signal from window.matchMedia. Your hook should turn that browser signal into React state and keep it current when the preference changes while the page is open.

Signature

function useDarkMode(defaultValue?: boolean): boolean;

defaultValue defaults to false. It is the safe value to return when window.matchMedia is unavailable, including server rendering. Once the hook mounts in a supporting browser, the media query's current matches value becomes the source of truth.

Examples

function ThemeStatus() {
  const isDarkMode = useDarkMode();

  return <p>{isDarkMode ? 'Dark preference' : 'Light preference'}</p>;
}
// System preference when the component mounts: dark
renderHook(() => useDarkMode()).result.current; // true

// The same mounted hook updates when the preference changes:
// dark -> light  => result.current becomes false
// light -> dark  => result.current becomes true

Notes

  • Use the exact query (prefers-color-scheme: dark). Read its current matches value after mount, then listen for its change event.
  • The browser signal wins after mount. If defaultValue is true but the media query currently reports false, the hook must settle on false.
  • Clean up the same listener. Remove the change handler from the same MediaQueryList object when the component unmounts.
  • Be environment-safe. If window or window.matchMedia is unavailable, return defaultValue and do not throw.
  • Only observe the system preference. Persisting a manual choice, toggling a class on <html>, and storing an override in localStorage are intentionally out of scope.