Tiny helper for CSS themes.
- One HTML attribute
data-set-themeto set theme theme. - Works with button, select, and checkbox
- Persists theme in localStorage
- Syncs all matching
data-set-themecontrols
<script src="https://cdn.jsdelivr.net/npm/theme-change@latest/index.js"></script>npm i theme-change@latestimport { themeChange } from "theme-change";
themeChange();Use themeChange(false) when controls are mounted after initial page load.
React
import { useEffect } from "react";
import { themeChange } from "theme-change";
useEffect(() => {
themeChange(false);
}, []);Vue
import { onMounted } from "vue";
import { themeChange } from "theme-change";
export default {
setup() {
onMounted(() => {
themeChange(false);
});
},
};Svelte
import { onMount } from "svelte";
import { themeChange } from "theme-change";
onMount(() => {
themeChange(false);
});Astro
---
import { themeChange } from "theme-change";
---
<script>
themeChange(false);
</script>Use daisyUI themes, or define your own theme tokens:
:root {
--my-color: #fff;
}
[data-theme="dark"] {
--my-color: #000;
}
[data-theme="pink"] {
--my-color: #ffabc8;
}
body {
background-color: var(--my-color);
}Notes:
- For checkbox: checked sets theme, unchecked clears theme.
- For rotate button: each click moves to the next item and loops.
- Controls with the same
data-keystay in sync.
<button data-set-theme="" data-act-class="ACTIVE"></button>
<button data-set-theme="dark" data-act-class="ACTIVE"></button>
<button data-set-theme="pink" data-act-class="ACTIVE"></button>Like data-act-class, but sets an arbitrary HTML attribute (instead of a class) on a button while its theme is active, and removes it when inactive. Useful for accessibility state such as aria-pressed or aria-current.
<!-- name:value β active: aria-pressed="true", inactive: attribute removed -->
<button data-set-theme="dark" data-act-attribute="aria-pressed:true"></button>
<!-- bare name (no colon) β boolean presence: active: aria-current="", inactive: removed -->
<button data-set-theme="pink" data-act-attribute="aria-current"></button>Notes:
- Syntax is
name[:value]. Only the first colon splits name and value, so the value may itself contain colons (e.g.data-act-attribute="title:Active: dark"). - When inactive the attribute is fully removed (not set to a falsy value).
- Button-only, same as
data-act-classβ ignored on<select>and checkbox controls. - Can be combined with
data-act-classon the same element. - Also works with the legacy
data-toggle-themebuttons.
<select data-set-theme data-key="admin-panel"></select>
<button data-set-theme="dark" data-key="front-page"></button>
<input type="checkbox" value="pink" data-set-theme data-key="premium-user-theme" />Legacy v2 attributes still work:
data-toggle-themedata-choose-theme



