How to implement dark mode in React
Implementing dark mode enhances user experience by providing eye-friendly viewing options and modern application aesthetics. As the creator of CoreUI with 25 years of development experience, I’ve implemented dark mode in numerous enterprise applications. The most robust approach uses React Context API for global theme state management combined with CSS custom properties for seamless theme switching. This method ensures consistent theming across all components while maintaining user preferences.
Use Context API with CSS custom properties and localStorage for persistent dark mode functionality.
import React, { createContext, useContext, useEffect, useState } from 'react'
const ThemeContext = createContext()
export const ThemeProvider = ({ children }) => {
const [isDark, setIsDark] = useState(() => {
const saved = localStorage.getItem('theme')
return saved === 'dark'
})
useEffect(() => {
document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light')
localStorage.setItem('theme', isDark ? 'dark' : 'light')
}, [isDark])
const toggleTheme = () => setIsDark(!isDark)
return (
<ThemeContext.Provider value={{ isDark, toggleTheme }}>
{children}
</ThemeContext.Provider>
)
}
export const useTheme = () => {
const context = useContext(ThemeContext)
if (!context) throw new Error('useTheme must be used within ThemeProvider')
return context
}
// Usage in component
const DarkModeToggle = () => {
const { isDark, toggleTheme } = useTheme()
return (
<button onClick={toggleTheme}>
{isDark ? '☀️ Light Mode' : '🌙 Dark Mode'}
</button>
)
}
This implementation creates a theme context that manages dark mode state globally. The useEffect hook updates the document’s data-theme attribute and persists the preference in localStorage. CSS custom properties can then target [data-theme="dark"] for styling. The custom hook provides a clean interface for components to access and modify theme state.
Best Practice Note:
This is the same reliable theming approach we use in CoreUI components for consistent dark mode support. Define your color tokens as CSS custom properties in the root scope and leverage the data-theme attribute for seamless theme transitions.



