The core library for Theme Token. Handles validation, parsing, and transformation of themes between raw CSS, on-chain storage format, and ShadCN Registry format.
ShadCN CLI (bunx shadcn add <url>) expects a specific JSON format with resolved color values—not raw CSS. This SDK bridges that gap.
flowchart LR
A[Raw CSS] -->|parseCss| B[ThemeToken JSON]
B -->|inscribe| C[Bitcoin]
C -->|fetch| D[Registry API]
D -->|toShadcnRegistry| E[ShadCN Format]
E -->|bunx shadcn add| F[Your Project]
bun add @theme-token/sdkConvert raw CSS into structured JSON for inscription. Automatically resolves var() references.
import { parseCss } from "@theme-token/sdk";
const css = `
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--primary: oklch(0.6 0.15 250);
--primary-foreground: oklch(0.98 0 0);
--radius: 0.5rem;
/* ... */
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.98 0 0);
/* ... */
}
`;
const result = parseCss(css, "My Theme");
if (result.valid) {
console.log(result.theme); // Ready to inscribe
}import { toShadcnRegistry } from "@theme-token/sdk";
const registryItem = toShadcnRegistry(theme);
// { $schema, name, type: "registry:style", cssVars: { light, dark } }import { fetchThemeByOrigin } from "@theme-token/sdk";
const published = await fetchThemeByOrigin("85702d92...cf_0");
if (published) {
console.log(published.theme.name);
}import { applyThemeMode } from "@theme-token/sdk";
applyThemeMode(theme, "dark");For React applications, use the dedicated hook from the /react entry:
import { useThemeToken } from "@theme-token/sdk/react";
function ThemePicker({ ordinals }) {
const {
themeTokens, // Filtered ThemeToken ordinals
activeOrigin, // Currently applied theme origin
loadTheme, // Load theme by origin
resetTheme, // Reset to default
isLoading, // Loading state
error // Error state
} = useThemeToken(ordinals);
return (
<div>
{themeTokens.map(t => (
<button
key={t.origin}
onClick={() => loadTheme(t.origin)}
disabled={isLoading}
>
{t.origin === activeOrigin ? "✓ " : ""}{t.origin.slice(0, 8)}...
</button>
))}
<button onClick={resetTheme}>Reset</button>
</div>
);
}The hook automatically:
- Filters ordinals for
map.app === "ThemeToken" - Persists selection to localStorage
- Restores saved theme on mount
- Detects light/dark mode from document
import { toCss } from "@theme-token/sdk";
const css = toCss(theme);
// :root { --background: oklch(...); ... }
// .dark { --background: oklch(...); ... }| Function | Description |
|---|---|
parseCss(css, name?) |
Parse CSS string to ThemeToken, resolving var() references |
validateThemeToken(data) |
Validate unknown JSON against schema |
themeTokenSchema |
Zod schema for direct validation |
| Function | Description |
|---|---|
toShadcnRegistry(theme) |
Convert to ShadCN Registry format |
toCss(theme) |
Convert to CSS string |
toJson(theme, pretty?) |
Convert to JSON string |
| Function | Description |
|---|---|
fetchThemeByOrigin(origin) |
Fetch theme from blockchain |
fetchPublishedThemes() |
Fetch all published themes |
getRegistryUrl(origin) |
Get registry URL for ShadCN CLI |
| Function | Description |
|---|---|
applyTheme(styles) |
Apply style props to document |
applyThemeMode(theme, mode) |
Apply light or dark mode |
getCurrentTheme() |
Read current theme from DOM |
clearTheme() |
Remove all theme variables |
| Export | Description |
|---|---|
useThemeToken(ordinals) |
React hook for managing ThemeToken ordinals |
interface ThemeToken {
$schema: string;
name: string;
author?: string;
styles: {
light: ThemeStyleProps;
dark: ThemeStyleProps;
};
}Colors use OKLCH: oklch(L C H) where L is lightness (0–1), C is chroma (0–0.4), H is hue (0–360).
MIT