Skip to content

Solid

@theme-kit/solid

SignalsContext

Signals-first theming with context provider, getters and scoped subtrees.

Installation

Install the package for your framework alongside @theme-kit/core.

bash
pnpm add @theme-kit/solid

Quick Start

Start from scratch — install the package, then wrap your app in the provider at the entry point shown below.

main.tsx
tsx
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")!);
Every integration re-exports the full @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.

ThemeSwitcher.tsx
tsx
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.

Toggle light / dark
tsx
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.

Undo / redo theme changes
tsx
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.

Scope a subtree
tsx
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.

Lifecycle events
tsx
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.

Smooth theme transitions
tsx
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.

history + scope
tsx
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

ExportDescription
ThemeProviderContext provider with DOM + CSS variable bindings.

Signals

ExportDescription
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

ExportDescription
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 subpathsUse `@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

ExportDescription
transition propPass `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

ExportDescription
ThemeScopeScoped theming component for subtrees.
Solid — Theme Kit