How to implement dark mode in React
Implementing dark mode in React applications improves user experience by reducing eye strain and providing visual preferences that adapt to user environments. As the creator of CoreUI with over 25 years of development experience, I’ve built theme switching systems across numerous production applications. The most effective approach is using React Context with CSS custom properties and localStorage persistence for consistent theme management. This provides seamless theme switching with proper state management and user preference persistence across browser sessions.
Use React Context with CSS custom properties and localStorage to implement persistent dark mode functionality with smooth theme transitions.
import { createContext, useContext, useState, useEffect } from 'react'
const ThemeContext = createContext()
export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light')
useEffect(() => {
const savedTheme = localStorage.getItem('theme') || 'light'
setTheme(savedTheme)
document.documentElement.setAttribute('data-theme', savedTheme)
}, [])
const toggleTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light'
setTheme(newTheme)
localStorage.setItem('theme', newTheme)
document.documentElement.setAttribute('data-theme', newTheme)
}
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
)
}
export function useTheme() {
const context = useContext(ThemeContext)
if (!context) {
throw new Error('useTheme must be used within ThemeProvider')
}
return context
}
// Component usage
function App() {
const { theme, toggleTheme } = useTheme()
return (
<div className="app">
<header>
<h1>Dark Mode Demo</h1>
<button onClick={toggleTheme}>
Switch to {theme === 'light' ? 'Dark' : 'Light'} Mode
</button>
</header>
<main>
<p>Content that adapts to theme changes</p>
</main>
</div>
)
}
This implementation uses React Context to manage theme state globally, localStorage for persistence across sessions, and CSS custom properties for styling. The data-theme attribute on the document root enables CSS to respond to theme changes. The custom hook useTheme provides easy access to theme functionality throughout the component tree.
Best Practice Note:
This dark mode pattern is used in CoreUI’s theming system for consistent, professional theme switching. Consider detecting user’s system preference with prefers-color-scheme media query and implementing smooth transitions between themes for enhanced user experience.



