Solid
@theme-kit/solid
Signals-first theming with context provider, getters and scoped subtrees.
Installation
Install the package for your framework alongside @theme-kit/core.
pnpm add @theme-kit/solidQuick Start
Start from scratch — install the package, then wrap your app in the provider at the entry point shown below.
1import { render } from "solid-js/web";
2import { ThemeProvider } from "@theme-kit/solid";
3import App from "./App";
4import { themes } from "./themes";
5
6render(() => (
7 <ThemeProvider themes={themes} defaultTheme="mint-light">
8 <App />
9 </ThemeProvider>
10), document.getElementById("root")!);@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.
1import { ThemeProvider, useTheme } from "@theme-kit/solid";
2
3function ThemeSwitcher() {
4 const { theme, toggleTheme } = useTheme();
5 return <button onClick={toggleTheme}>{theme().name}</button>;
6}
7
8export function App() {
9 return (
10 <ThemeProvider themes={themes}>
11 <ThemeSwitcher />
12 </ThemeProvider>
13 );
14}What's Available
@theme-kit/solid ships 14 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.
Provider
Signals
Library adapters
Transition
Components
Use Cases
The important features in practice — copy any of these straight into your app.
Toggle light / dark
useTheme returns signals and getters for fine-grained reactivity.
1import { useTheme } from "@theme-kit/solid";
2
3function ThemeToggle() {
4 const { theme, mode, setMode, toggleTheme } = useTheme();
5 return (
6 <div>
7 <button onClick={() => toggleTheme()}>{theme().name}</button>
8 <button onClick={() => setMode("dark")}>Dark</button>
9 <span>{mode()}</span>
10 </div>
11 );
12}Undo / redo theme changes
History controls as signals, plus live runtime updates.
1import { useThemeHistory, useThemeRuntime } from "@theme-kit/solid";
2
3function HistoryControls() {
4 const { undo, redo, canUndo, canRedo } = useThemeHistory();
5 const runtime = useThemeRuntime();
6 return (
7 <div>
8 <button onClick={() => undo()} disabled={!canUndo()}>Undo</button>
9 <button onClick={() => redo()} disabled={!canRedo()}>Redo</button>
10 <button onClick={() => runtime.update({ colors: { primary: "#6366f1" } })}>
11 Make primary indigo
12 </button>
13 </div>
14 );
15}Scope a subtree
ThemeScope themes a subtree with scoped CSS variables.
1import { ThemeScope } from "@theme-kit/solid";
2
3function Dashboard() {
4 return (
5 <>
6 <Sidebar />
7 <ThemeScope theme="forest">
8 <DataViz />
9 </ThemeScope>
10 </>
11 );
12}Lifecycle events
Subscribe to lifecycle events and install theme packs.
1import { onMount } from "solid-js";
2import { useThemeLifecycle, useThemePacks } from "@theme-kit/solid";
3
4function Telemetry() {
5 const { on } = useThemeLifecycle();
6 const usePack = useThemePacks();
7 onMount(() => on("beforeThemeChange", (e) => console.log(e.next.name)));
8 return (
9 <button onClick={() => usePack({ name: "a11y", themes: highContrast })}>
10 Apply High Contrast pack
11 </button>
12 );
13}Smooth theme transitions
Enable CSS transitions on theme changes for a polished user experience.
1import { ThemeProvider } from "@theme-kit/solid";
2
3export function App() {
4 return (
5 <ThemeProvider
6 themes={themes}
7 transition={{ enabled: true, duration: 300, easing: "ease-in-out" }}
8 >
9 <YourApp />
10 </ThemeProvider>
11 );
12}More Examples
Scoped theming, history controls, and framework-specific patterns.
1import { ThemeProvider, ThemeScope, useThemeHistory, type ThemeTransitionOptions } from "@theme-kit/solid";
2
3const transition: ThemeTransitionOptions = { duration: 300, easing: "ease" };
4
5export function App() {
6 return (
7 <ThemeProvider themes={themes}>
8 <ThemeScope theme="forest" transition={transition}>
9 <span>Always forest</span>
10 </ThemeScope>
11 <HistoryControls />
12 </ThemeProvider>
13 );
14}
15
16function HistoryControls() {
17 const { undo, redo, canUndo, canRedo } = useThemeHistory();
18 return (
19 <div>
20 <button onClick={undo} disabled={!canUndo}>Undo</button>
21 <button onClick={redo} disabled={!canRedo}>Redo</button>
22 </div>
23 );
24}API Reference
Provider
| Export | Description |
|---|---|
ThemeProvider | Context provider with DOM + CSS variable bindings. |
Signals
| Export | Description |
|---|---|
useTheme() | Signals for `theme`, `mode`, `family` with getter access and setters. |
useThemeHistory() | Undo / redo / jump through theme history. |
useThemeBatch() | Atomic, coalesced updates. |
useThemeSnapshot() / useThemeRestore() | Serialize and restore runtime state. |
useThemeLifecycle() | Subscribe to lifecycle events. |
useThemePacks() | Install theme packs at runtime. |
useThemeSchedule() | Reactive sunrise/sunset controller with signal-backed `enabled`, `active`, `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. |