Themes and registries
Implement dark mode
Apply the documented dark-mode pattern for the framework and prevent an unreadable first render or a theme that ignores system preference.
8 minute lesson
Dark mode works by applying an alternate set of theme variables under a class or another documented selector.
Follow the current guide for Next.js or Vite because initialization and hydration differ by framework. Decide whether the interface follows the system only or offers light, dark, and system choices. Persist a manual choice and apply the initial theme early enough to avoid a flash of the wrong colors.
Treat light, dark, and system as three preference states. “System” is not another fixed palette: it resolves through prefers-color-scheme and must react when that preference changes. A manual light or dark choice should stop following the system until the user chooses system again.
Server-rendered HTML cannot read browser storage. The framework-specific provider pattern coordinates the first client render with the class placed on the document; use hydration suppression only where the documented theme mechanism requires it, not to hide unrelated mismatches. Watch the first paint on a throttled reload, not only the settled page.
Every semantic state needs a dark value. Charts, illustrations, code blocks, selection, disabled text, overlays, and focus rings often expose gaps that a background-and-foreground swap misses.
Implement the documented provider and a labelled three-state control. Reload each saved state under network throttling, change the operating-system preference while “system” is active, and audit every interactive state in both resolved themes.
Lesson completed