Skip to content

Svelte Integration

This guide shows you how to integrate the Axiomatic Color into a Svelte application using TypeScript.

First, install the CLI and generate your theme CSS and TypeScript definitions.

Terminal window
npm install -D @axiomatic-design/color
npx axiomatic init
npx axiomatic build --out ./src/theme.css
npx axiomatic export --format typescript --out ./src/lib/theme.ts

Import the CSS in your root layout (e.g., src/routes/+layout.svelte):

<script>
import '../theme.css';
</script>
<slot />

We can create a reusable <Surface> component.

src/lib/components/Surface.svelte
<script lang="ts">
import { tokens } from '$lib/theme';
import type { HTMLAttributes } from 'svelte/elements';
interface Props extends HTMLAttributes<HTMLElement> {
variant: keyof typeof tokens.surface;
as?: string;
children?: import('svelte').Snippet;
}
let {
variant,
as = 'div',
class: className = '',
children,
...rest
}: Props = $props();
const surfaceClass = tokens.surface[variant];
</script>
<svelte:element
this={as}
class="{surfaceClass} {className}"
{...rest}
>
{@render children?.()}
</svelte:element>

We can wrap the ThemeManager in a Svelte 5 reactive class to handle state management.

src/lib/theme.svelte.ts
import { ThemeManager, type ThemeMode } from "@axiomatic-design/color/browser";
export class ThemeService {
private manager: ThemeManager;
mode = $state<ThemeMode>("system");
constructor() {
this.manager = new ThemeManager();
// Restore saved preference
if (typeof localStorage !== "undefined") {
const saved = localStorage.getItem("theme") as ThemeMode | null;
if (saved) {
this.setMode(saved);
}
}
}
setMode(mode: ThemeMode) {
this.mode = mode;
this.manager.setMode(mode);
localStorage.setItem("theme", mode);
}
toggle() {
const next = this.manager.resolvedMode === "light" ? "dark" : "light";
this.setMode(next);
}
}
// Export a singleton instance
export const theme = new ThemeService();
src/routes/+page.svelte
<script lang="ts">
import Surface from '$lib/components/Surface.svelte';
import { theme } from '$lib/theme.svelte';
import { tokens } from '$lib/theme';
</script>
<Surface variant="page" style="min-height: 100vh; padding: 2rem;">
<header style="display: flex; justify-content: space-between;">
<h1 style="color: {tokens.context.text.high}">My App</h1>
<button onclick={() => theme.toggle()}>
{theme.mode === 'light' ? '🌙' : '☀️'}
</button>
</header>
<main>
<Surface variant="card" style="padding: 2rem; border-radius: 8px;">
<h2 style="color: {tokens.context.text.high}">Hello World</h2>
<p style="color: {tokens.context.text.subtle}">
This card is automatically themed based on its context.
</p>
</Surface>
</main>
</Surface>