Theme Provider

Utility

Theme context provider with persistence.

Preview

ThemeProvider manages light/dark theme state for your application. Wrap your app root with it.

<ThemeProvider>
  <App />
</ThemeProvider>

Usage

example.jsx
import { ThemeProvider, useTheme } from "@/components/ui/theme-provider";

export default function Example() {
  return <ThemeProvider />;
}

Source Code

Copy this file into components/ui/theme-provider.jsx in your project.

theme-provider.jsx
"use client";

import { createContext, useContext, useEffect, useState } from "react";

const ThemeContext = createContext({ theme: "system", setTheme: () => {} });

function ThemeProvider({ children, defaultTheme = "system", storageKey = "paramui-theme" }) {
  const [theme, setTheme] = useState(defaultTheme);

  useEffect(() => {
    const stored = localStorage.getItem(storageKey);
    if (stored) setTheme(stored);
  }, [storageKey]);

  useEffect(() => {
    const root = document.documentElement;
    root.classList.remove("light", "dark");
    if (theme === "system") {
      const sys = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
      root.classList.add(sys);
    } else {
      root.classList.add(theme);
    }
    localStorage.setItem(storageKey, theme);
  }, [theme, storageKey]);

  return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider>;
}

function useTheme() { return useContext(ThemeContext); }

export { ThemeProvider, useTheme };

Quick Install

Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.

npm install clsx tailwind-merge