Astro
@theme-kit/astro
Islands-friendly theming with a shared global runtime, zero-flash bootstrap, and the same framework-neutral adapter boundary.
Installation
Install the package for your framework alongside @theme-kit/core.
pnpm add @theme-kit/astroQuick Start
Start from scratch — install the package, then wrap your app in the provider at the entry point shown below.
1---
2import { ThemeProviderClient } from "@theme-kit/astro";
3import ThemeSwitcher from "../components/ThemeSwitcher.astro";
4import { themes } from "./themes";
5---
6
7<html>
8 <head>
9 <title>My site</title>
10 </head>
11 <body>
12 <ThemeProviderClient themes={themes} defaultTheme="mint-light" />
13 <ThemeSwitcher client:load />
14 </body>
15</html>@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---
2import { ThemeProviderClient } from "@theme-kit/astro";
3import ThemeSwitcher from "../components/ThemeSwitcher.astro";
4---
5
6<ThemeProviderClient themes={themes} />
7
8<ThemeSwitcher client:load />What's Available
@theme-kit/astro ships 8 exports in 3 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
Bootstrap & Sync
Transition
Use Cases
The important features in practice — copy any of these straight into your app.
Theme an island
ThemeProviderClient themes a client island with a blocking bootstrap.
1---
2import { ThemeProviderClient } from "@theme-kit/astro";
3---
4
5<ThemeProviderClient themes={themes} defaultTheme="light">
6 <ThemeSwitcher client:load />
7</ThemeProviderClient>Zero-flash script + CSS map
Build the blocking script and precompute CSS variables server-side.
1---
2import { createBlockingScript, buildThemeCssMap, computeFingerprint } from "@theme-kit/astro";
3
4const fingerprint = computeFingerprint(themes, "light");
5const cssMap = buildThemeCssMap(themes);
6const script = createBlockingScript(fingerprint, cssMap);
7---
8
9<html data-theme="light" style={cssMap["sunrise-light"]}>
10 <head><Fragment set:html={script} /></head>
11 <body><slot /></body>
12</html>Scope a subtree
ThemeScope works inside client components too.
1---
2import { ThemeProviderClient, ThemeScope } from "@theme-kit/astro";
3---
4
5<ThemeProviderClient themes={themes}>
6 <ThemeScope theme="forest" client:load>
7 <DataViz />
8 </ThemeScope>
9</ThemeProviderClient>Shared runtime across islands
getGlobalRuntime/setGlobalRuntime let islands share one runtime.
1---
2import { getGlobalRuntime } from "@theme-kit/astro";
3
4const runtime = getGlobalRuntime();
5console.log(runtime?.store.get().name ?? "not initialised yet");
6---Smooth theme transitions
Enable CSS transitions on theme changes for a polished user experience.
1---
2import { ThemeProviderClient } from "@theme-kit/astro";
3---
4
5<ThemeProviderClient
6 themes={themes}
7 defaultTheme="light"
8 transition={{ enabled: true, duration: 300, easing: "ease-in-out" }}
9>
10 <slot />
11</ThemeProviderClient>More Examples
Scoped theming, history controls, and framework-specific patterns.
1---
2// A client island consuming the shared global runtime
3---
4<button id="theme-switcher">Toggle</button>
5
6<script>
7 import { useTheme, getGlobalRuntime } from "@theme-kit/astro";
8
9 // Runs after ThemeProviderClient hydrated the shared runtime
10 const { toggleTheme } = useTheme();
11 document
12 .getElementById("theme-switcher")
13 ?.addEventListener("click", toggleTheme);
14
15 const runtime = getGlobalRuntime(); // same instance across islands
16</script>API Reference
Provider
| Export | Description |
|---|---|
ThemeProviderClient | Client island provider that wires the runtime. |
Full hook set + ThemeScope | `useTheme`, history, batch, snapshot, lifecycle, packs, and scoped subtrees. |
Bootstrap & Sync
| Export | Description |
|---|---|
createBlockingScript / buildThemeCssMap / darkModeCSSTemplate | Zero-flash bootstrap utilities for server-rendered islands. |
createAstroThemePersistence() | Astro-flavored persistence adapter. |
computeFingerprint() | Cookie/config fingerprinting for stale-state detection. |
getGlobalRuntime() / setGlobalRuntime() | Share one runtime across all islands on the page. |
Transition
| Export | Description |
|---|---|
transition prop | Pass `transition` to ThemeProviderClient 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, getGlobalRuntime() then runtime.store.set(theme, { suppressTransition: true }) applies immediately without animating. For full control, compose createTransitionPlan + runThemeAnimation from @theme-kit/core. |