Member-only story
Dark Theme in React 19 and Typescript with Zustand
2 min readJan 18, 2025
Managing themes in a React application can greatly enhance the user experience by supporting dark, light, and system themes. This article will guide you through implementing theme management using Zustand, a lightweight state management library.
We first create a Zustand store to manage the theme state. The store includes a theme
state and a setTheme
function for updating the theme.
import { create } from "zustand";
type Theme = "light" | "dark" | "system";
type ThemeState = {
theme: Theme;
setTheme: (theme: Theme) => void;
};
export const useThemeStore = create<ThemeState>((set) => ({
theme: "system",
setTheme: (theme: Theme) => {
localStorage.setItem("vite-ui-theme", theme);
set({ theme });
},
}));
This store ensures the theme selection persists by saving it to localStorage
.
Step 2: Create the ThemeProvider Component
The ThemeProvider
component initializes the theme state and synchronizes it with the DOM and system preferences.
import { useEffect } from "react";
import { useThemeStore } from "./useThemeStore";
type Theme = "light" | "dark" | "system";
export function ThemeProvider({
defaultTheme = "system",
}: {
defaultTheme?: Theme;
}) {
const { theme, setTheme } = useThemeStore();
useEffect(() => {
const storedTheme =
(localStorage.getItem("vite-ui-theme") as Theme) || defaultTheme;
setTheme(storedTheme);
}…