Dark Mode in Next.js with next-themes
Dark mode is expected in modern apps. Done well it's seamless; done poorly it flashes white on every page load. Here's how to do it right in Next.js.
Use next-themes
The `next-themes` library handles the hard parts: reading the system preference, persisting the user's choice, and — crucially — applying the theme class before first paint so there's no flash of the wrong theme. Wrap your app in its provider and you're most of the way there.
Drive colors with CSS variables
Rather than sprinkling `dark:` variants everywhere, define your colors as CSS variables and switch their values based on the theme. Your components reference semantic tokens like `background` and `foreground`, and the theme decides what those resolve to — far more maintainable.
Build the toggle
- Offer light, dark, and system options so users can defer to their OS.
- Guard against hydration mismatch by only rendering the toggle's current state after mount.
- Give the toggle an accessible label and keyboard support.
Test both themes
It's easy to ship a component that looks great in light mode and unreadable in dark. Build and review every screen in both themes — pay special attention to borders, shadows, and images that assume a light background.
Every KitCraft template ships with flicker-free dark mode via next-themes and a token-based color system, so both themes look intentional on every screen.
