@alexsantosquispe/use-theme-hook
v1.0.3
Published
A React hook for managing themes
Maintainers
Readme
🎨 use-theme-hook 🌗
A lightweight React hook for managing themes (light, dark, and system) with automatic persistence to localStorage.
Package name on npm: @alexsantosquispe/use-theme-hook
✨ Why use this hook?
- ✅ Minimal API, easy to reason about
- 🧩 Zero runtime dependencies
- 🎯 Tailwind CSS–friendly (
darkclass strategy) - 💾 Persistent theme across sessions
- 🧪 Fully typed and unit tested
- 📦 Works with both ESM and CommonJS consumers
⚠️ Client-side only
This library relies on window and localStorage.
When using SSR frameworks like Next.js, Remix, or Gatsby, ensure it runs only on the client (e.g. inside client components or useEffect).
📦 Installation
pnpm
pnpm add @alexsantosquispe/use-theme-hooknpm
npm install @alexsantosquispe/use-theme-hook🚀 Usage
- First, wrap your application with the
ThemeProviderto provide the theme context to all your components.
// src/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { ThemeProvider } from "@alexsantosquispe/use-theme-hook";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<ThemeProvider>
<App />
</ThemeProvider>
</React.StrictMode>
);With Tailwind CSS 🎯
This hook works by adding a dark class to the <html> element when the dark theme is active. You can use this to style your application accordingly.
If you are using Tailwind CSS, add the following line to your global CSS file (e.g., index.css) to enable dark mode variants:
@custom-variant dark (&:is(.dark *));This will allow you to use the dark: prefix for your utility classes. 🎨
For more information, see the Tailwind CSS documentation on toggling dark mode manually. 📖
- Next, use the
useThemehook in any component to access the current theme and the function to update it.
// src/App.tsx
import { THEME_TYPES, useTheme } from "@alexsantosquispe/use-theme-hook";
function App() {
const { theme, setTheme } = useTheme();
return (
<div>
<h1>Current Theme: {theme}</h1>
<button onClick={() => setTheme(THEME_TYPES.LIGHT)}>Light</button>
<button onClick={() => setTheme(THEME_TYPES.DARK)}>Dark</button>
<button onClick={() => setTheme(THEME_TYPES.SYSTEM)}>System</button>
</div>
);
}
export default App;- Now you can use the tailwind styles for dark mode like this example:
<p className="text-black dark:text-white">Lorem ipsum...</p>- Happy coding!!
📚 API Reference
ThemeProvider
A React component that provides the theme context to its children. It should be used at the root of your application.
By default you are going to get light, dark, or system. If you just need a light and dark options you can set the flag allowSystemTheme to false in the ThemeProvider to disable that option.
// src/main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { ThemeProvider } from "@alexsantosquispe/use-theme-hook";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
{/* Here goes the change */}
<ThemeProvider allowSystemTheme={false}>
<App />
</ThemeProvider>
</React.StrictMode>
);Then you use the useTheme hook you are not going to get the system option.
// src/component/ThemeButton.tsx
import { THEME_TYPES, useTheme } from "@alexsantosquispe/use-theme-hook";
export const ThemeButton = () => {
const { theme, setTheme } = useTheme();
const toggleTheme = () => {
const newTheme =
theme === THEME_TYPES.DARK ? THEME_TYPES.LIGHT : THEME_TYPES.DARK;
setTheme(newTheme);
};
return (
<button onClick={toggleTheme}>
{theme === THEME_TYPES.DARK ? "Light" : "Dark"}
</button>
);
};useTheme()
A custom hook that returns the theme context.
theme: (ThemeType) The current active theme (light,dark, orsystem).setTheme: ((theme: ThemeType) => void) A function to update the current theme.
import { useTheme } from "@alexsantosquispe/use-theme-hook";
export const Component = () => {
const { theme, setTheme } = useTheme();
return <div>...</div>;
};THEME_TYPES 📋
An object containing the available theme constants:
LIGHT:'light'DARK:'dark'SYSTEM:'system'
You also can use the ThemeType if you need it.
import { THEME_TYPES, type ThemeType } from "@alexsantosquispe/use-theme-hook";
export const Component = () => {
const { theme, setTheme } = useTheme();
return <div>...</div>;
};⚙️ How It Works
This hook is designed to provide a seamless theme management experience. Here's a brief overview of its inner workings:
System Theme Detection: When the theme is set to
'system', the hook useswindow.matchMedia('(prefers-color-scheme: dark)')to automatically detect and apply the user's preferred system theme (light or dark).Persistence: To ensure the selected theme persists across sessions, the hook stores the current theme in
localStorageunder the key"uth-theme". When the application loads, it checks for this key and applies the stored theme. You can get the storedTheme using the functiongetStoredTheme.Theme Application: The hook applies the current theme by adding or removing the
darkclass to the<html>element. This allows you to use Tailwind CSS'sdark:variants to style your components for dark mode.
🤝 Contributing
Contributions are welcome! If you have any ideas, suggestions, or bug reports, please open an issue on the GitHub repository. If you'd like to contribute code, please fork the repository and submit a pull request. 🚀
📄 License
This project is licensed under the MIT License.
