Vue 3
@theme-kit/vue
Composables-first theming for Vue 3 with a provider component and scoped theming.
Installation
Install the package for your framework alongside @theme-kit/core.
pnpm add @theme-kit/vueQuick Start
Start from scratch — install the package, then wrap your app in the provider at the entry point shown below.
1<script setup>
2import { ThemeProvider } from "@theme-kit/vue";
3import { themes } from "./themes";
4</script>
5
6<template>
7 <ThemeProvider :themes="themes" default-theme="mint-light">
8 <YourView />
9 </ThemeProvider>
10</template>@theme-kit/core surface, so history, batching, snapshots, packs and lifecycle work the same way across frameworks.Implementation
Read and update theme state from any component using the framework-native primitives below.
1<script setup>
2import { useTheme } from "@theme-kit/vue";
3const { theme, mode, toggleTheme } = useTheme();
4</script>
5
6<template>
7 <button @click="toggleTheme">{{ theme.name }} · {{ mode }}</button>
8</template>What's Available
@theme-kit/vue ships 15 exports in 5 categories. Everything below is also documented in the full API reference. Click any export to reveal what it does and how to use it.
Setup
Composables
Library adapters
Transition
Components
Use Cases
The important features in practice — copy any of these straight into your app.
Toggle light / dark
useTheme exposes refs and setters — reactive in templates and scripts.
1<script setup>
2import { useTheme } from "@theme-kit/vue";
3const { theme, mode, family, setMode, setFamily, toggleTheme } = useTheme();
4</script>
5
6<template>
7 <button @click="toggleTheme">{{ theme.name }} · {{ mode }}</button>
8 <button @click="setMode('dark')">Dark</button>
9 <select v-model="family" @change="setFamily(family)">
10 <option value="neutral">Neutral</option>
11 <option value="mint">Mint</option>
12 </select>
13</template>Undo / redo theme changes
History state is reactive; use it to build undo/redo controls.
1<script setup>
2import { useThemeHistory, useThemeRuntime } from "@theme-kit/vue";
3const { undo, redo, canUndo, canRedo } = useThemeHistory();
4const runtime = useThemeRuntime();
5</script>
6
7<template>
8 <button :disabled="!canUndo" @click="undo">Undo</button>
9 <button :disabled="!canRedo" @click="redo">Redo</button>
10 <button @click="runtime.update({ colors: { primary: '#6366f1' } })">
11 Make primary indigo
12 </button>
13</template>Scope a subtree
ThemeScope applies a theme to a slot with scoped CSS variables.
1<script setup>
2import { ThemeScope, type ThemeTransitionOptions } from "@theme-kit/vue";
3
4const transition: ThemeTransitionOptions = { duration: 300, easing: "ease" };
5</script>
6
7<template>
8 <Sidebar />
9 <ThemeScope theme="forest" :transition="transition">
10 <DataViz />
11 </ThemeScope>
12</template>Lifecycle events
Subscribe to typed lifecycle events and react to changes.
1<script setup>
2import { onMounted } from "vue";
3import { useThemeLifecycle, useThemePacks } from "@theme-kit/vue";
4
5const { on } = useThemeLifecycle();
6const usePack = useThemePacks();
7
8onMounted(() => {
9 on("beforeThemeChange", (e) => console.log("changed to", e.next.name));
10});
11</script>
12
13<template>
14 <button @click="usePack({ name: 'a11y', themes: highContrast })">
15 Apply High Contrast pack
16 </button>
17</template>Smooth theme transitions
Enable CSS transitions on theme changes for a polished user experience.
1<script setup>
2import { ThemeProvider } from "@theme-kit/vue";
3</script>
4
5<template>
6 <ThemeProvider
7 :themes="themes"
8 :transition="{ enabled: true, duration: 300, easing: 'ease-in-out' }"
9 >
10 <YourView />
11 </ThemeProvider>
12</template>More Examples
Scoped theming, history controls, and framework-specific patterns.
1<script setup>
2import { useThemeHistory } from "@theme-kit/vue";
3const { undo, redo, canUndo, canRedo } = useThemeHistory();
4</script>
5
6<template>
7 <button @click="undo" :disabled="!canUndo">Undo</button>
8 <button @click="redo" :disabled="!canRedo">Redo</button>
9
10 <ThemeScope theme="forest">
11 <p>This subtree is always themed "forest".</p>
12 </ThemeScope>
13</template>API Reference
Setup
| Export | Description |
|---|---|
ThemeProvider | Provider component accepting every runtime option; auto-registered via `app.use` (`.install`). |
provideThemeRuntime() / useThemeRuntime() | Explicit provide/inject access to the runtime. |
Composables
| Export | Description |
|---|---|
useTheme() | Reactive refs for `theme`, `mode`, `family` plus `setMode`, `setFamily`, `toggleTheme`. |
useThemeHistory() | Undo / redo / jump through theme history. |
useThemeBatch() | Atomic, coalesced updates via `runtime.batch()`. |
useThemeSnapshot() / useThemeRestore() | Serialize and restore the full runtime state. |
useThemeLifecycle() | Subscribe to typed lifecycle events. |
useThemePacks() | Install theme packs at runtime. |
useThemeSchedule() | Reactive schedule state (a `Ref` with `enabled`, `status`, `sunrise`, `sunset`, `nextTransition`) plus `enable()`/`disable()`/`set()`. Configure via the `scheduled` prop on ThemeProvider. |
Library adapters
| Export | Description |
|---|---|
useShadcnTheme() / useBootstrapTheme() | Framework composables install the React-free CSS-variable adapter factories and dispose the returned adapter handle with the component lifecycle. |
useDaisyTheme() / useOpenPropsTheme() | Same adapter contract for DaisyUI and Open Props; the framework package supplies lifecycle wiring while the adapter factory stays framework-neutral. |
adapter factory subpaths | Use `@theme-kit/shadcn/factory`, `@theme-kit/bootstrap/factory`, `@theme-kit/daisyui/factory`, or `@theme-kit/open-props/factory` when you need the adapter without React. |
Transition
| Export | Description |
|---|---|
transition prop | Pass `transition` to ThemeProvider to enable CSS transitions on theme changes. |
runtime.store.set(theme, { suppressTransition: true }) | Runtime toggle — no mutation hook exists. The transition prop is fixed at runtime creation; for a one-off instant switch, get the runtime (useThemeRuntime() / getThemeRuntime()) then runtime.store.set(theme, { suppressTransition: true }) applies immediately without animating. For full control, compose createThemeDiff + createTransitionPlan + runThemeAnimation from @theme-kit/core. |
Components
| Export | Description |
|---|---|
ThemeScope | Scoped theming component for subtrees. |