npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

svelte-theme-picker

v1.1.1

Published

A beautiful, customizable theme picker component for Svelte applications

Downloads

24

Readme

svelte-theme-picker

A customizable theme picker component for Svelte 5 applications.

Features

  • 10 built-in themes (dark and light modes)
  • Fully customizable - add your own themes
  • Persists selection to localStorage
  • Applies CSS variables to your document
  • Svelte 5 runes compatible
  • Full TypeScript support
  • Floating button or inline mode (vertical or horizontal)
  • Preview mode - temporarily apply themes without persisting
  • JSON-driven themes - define themes in JSON with production/test filtering
  • Theme catalogs - organize themes with metadata, tags, and filtering
  • Headless mode - use the store without any UI for full programmatic control
  • Performance optimized - GPU-accelerated animations, batched DOM updates
  • Accessible - ARIA labels, keyboard navigation (Escape to close)

Installation

npm install svelte-theme-picker
# or
pnpm add svelte-theme-picker
# or
yarn add svelte-theme-picker

Basic Usage

<script>
  import { ThemePicker } from 'svelte-theme-picker';
</script>

<ThemePicker />

This adds a floating theme picker button to the bottom-right of your page.

Configuration

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | config | ThemePickerConfig | {} | Configuration options | | store | ThemeStore | undefined | Custom theme store | | position | 'bottom-right' \| 'bottom-left' \| 'top-right' \| 'top-left' | 'bottom-right' | Position of trigger button | | showTrigger | boolean | true | Show floating button (false = inline mode) | | layout | 'vertical' \| 'horizontal' | 'vertical' | Layout direction for inline mode | | onThemeChange | (id: string, theme: Theme) => void | undefined | Callback when theme changes |

Inline Layouts

<!-- Vertical list with names and descriptions -->
<ThemePicker showTrigger={false} layout="vertical" />

<!-- Horizontal grid of color swatches (compact) -->
<ThemePicker showTrigger={false} layout="horizontal" />

Configuration Options

interface ThemePickerConfig {
  storageKey?: string;      // localStorage key (default: 'svelte-theme-picker')
  defaultTheme?: string;    // Default theme ID (default: 'dreamy')
  themes?: Record<string, Theme>;  // Custom themes
  cssVarPrefix?: string;    // CSS variable prefix
}

SSR Support (Preventing Flash)

When using SvelteKit with SSR, themes are applied after JavaScript loads, causing a flash of unstyled content (FOUC). Use the ThemeHead component or SSR utilities to prevent this.

Using ThemeHead Component (Recommended)

The easiest way to prevent theme flash in SvelteKit:

<!-- src/routes/+layout.svelte -->
<script>
  import { ThemeHead, ThemePicker, defaultThemes } from 'svelte-theme-picker';
</script>

<ThemeHead
  themes={defaultThemes}
  storageKey="my-app-theme"
  defaultTheme="dreamy"
  preloadFonts={true}
/>

<ThemePicker config={{ themes: defaultThemes, storageKey: 'my-app-theme' }} />

<slot />

The ThemeHead component:

  • Injects a blocking script that applies CSS variables before first paint
  • Adds no-transitions class to prevent transition animations during hydration
  • Optionally preloads Google Fonts for all themes

ThemeHead Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | themes | Record<string, Theme> | required | All available themes | | storageKey | string | 'svelte-theme-picker' | localStorage key | | defaultTheme | string | first theme | Default theme ID | | cssVarPrefix | string | '' | CSS variable prefix | | preventTransitions | boolean | true | Prevent transition animations during hydration | | preloadFonts | boolean | false | Enable Google Fonts preloading | | fontConfig | FontConfig | { provider: 'google' } | Font preloading configuration |

Using SSR Utilities Directly

For more control, use the SSR utilities to generate blocking scripts:

// src/hooks.server.ts
import { generateSSRHead } from 'svelte-theme-picker';
import { myThemes } from './themes';

export async function handle({ event, resolve }) {
  return resolve(event, {
    transformPageChunk: ({ html }) => {
      const ssrHead = generateSSRHead({
        themes: myThemes,
        storageKey: 'my-app-theme',
        defaultTheme: 'dreamy',
      });
      return html.replace('</head>', `${ssrHead}</head>`);
    }
  });
}

Removing No-Transitions Class

After hydration, remove the no-transitions class to enable animations:

<!-- src/routes/+layout.svelte -->
<script>
  import { browser } from '$app/environment';
  import { onMount } from 'svelte';

  onMount(() => {
    // Small delay to ensure hydration is complete
    setTimeout(() => {
      document.documentElement.classList.remove('no-transitions');
    }, 50);
  });
</script>

SSR Utility Functions

import {
  generateBlockingScript,  // Generate minified blocking script string
  generateSSRHead,         // Generate complete head HTML (script + styles + fonts)
  applyThemeToElement,     // Apply theme to an element (sync, for blocking scripts)
  getThemeCSS,            // Get CSS variable declarations as string
  extractFonts,           // Extract font names from a theme
  generateFontPreloadLinks, // Generate Google Fonts preload links
  themeSchema,            // CSS variable mapping (for consistency)
} from 'svelte-theme-picker';

Cross-Tab Synchronization

Enable automatic theme sync across browser tabs:

<script>
  import { createThemeStore, ThemePicker } from 'svelte-theme-picker';

  const store = createThemeStore({
    syncTabs: true,  // Enable cross-tab sync
    storageKey: 'my-app-theme',
  });
</script>

<ThemePicker store={store} />

When a user changes the theme in one tab, all other tabs will automatically update. The store listens for storage events and syncs the theme state.

To clean up listeners when done:

store.destroy(); // Removes storage event listener

External Store Synchronization

If you're using an external store and the ThemePicker doesn't update when the store changes externally, use the {#key} pattern to force a re-render:

<script>
  import { ThemePicker, createThemeStore } from 'svelte-theme-picker';

  const themeStore = createThemeStore({ /* config */ });
  let currentThemeId = $state('dreamy');

  // Subscribe to track external changes
  themeStore.subscribe((themeId) => {
    currentThemeId = themeId;
  });
</script>

<!-- Force re-render when theme changes externally -->
{#key currentThemeId}
  <ThemePicker store={themeStore} />
{/key}

Note: The ThemePicker component captures its configuration once at mount. This is intentional for performance. Use {#key} to create a new instance when props need to change.

Headless Mode (No UI)

The ThemePicker component is completely optional. You can use just the store and utilities for full programmatic control without rendering any UI. This is useful when:

  • You want to control themes from your own settings page
  • Themes are set based on user preferences from a database
  • You're building a custom theme switcher UI
  • You want to disable user theme switching entirely
<script>
  // No ThemePicker component needed!
  import { themeStore, applyTheme, defaultThemes } from 'svelte-theme-picker';
  import { onMount } from 'svelte';

  onMount(() => {
    // Load theme from user preferences, database, API, etc.
    const userTheme = getUserPreference() || 'dreamy';
    themeStore.setTheme(userTheme);
    applyTheme(defaultThemes[userTheme]);

    // Optionally subscribe to persist changes
    return themeStore.subscribe((themeId) => {
      saveUserPreference(themeId);
    });
  });
</script>

<!-- Your app content - no picker UI rendered -->
<slot />

You get all the benefits (localStorage persistence, CSS variable application, TypeScript types) without any visible theme picker.

Preview Mode (Temporary Themes)

Perfect for form-based theme selection where you want to preview themes without persisting them:

<script>
  import { themeStore, applyTheme, defaultThemes } from 'svelte-theme-picker';
  import { onMount } from 'svelte';

  let selectedTheme = 'dreamy';

  onMount(() => {
    // When the page unmounts, revert to persisted theme
    return () => {
      themeStore.revertPreview();
    };
  });

  function previewTheme(themeId: string) {
    selectedTheme = themeId;
    // Preview without persisting to localStorage
    themeStore.previewTheme(themeId);
    applyTheme(defaultThemes[themeId]);
  }

  function saveTheme() {
    // Persist the selection
    themeStore.setTheme(selectedTheme);
  }
</script>

<select onchange={(e) => previewTheme(e.target.value)}>
  {#each Object.entries(defaultThemes) as [id, theme]}
    <option value={id}>{theme.name}</option>
  {/each}
</select>

<button onclick={saveTheme}>Save Theme</button>

Store Preview Methods

interface ThemeStore {
  // ... standard methods ...

  /** Preview a theme temporarily without persisting */
  previewTheme: (themeId: string) => void;

  /** Revert from preview back to the persisted theme */
  revertPreview: () => void;

  /** Check if currently in preview mode */
  isPreviewMode: () => boolean;

  /** Get the persisted theme ID (ignores preview) */
  getPersistedThemeId: () => string;
}

Theme Catalogs

For larger applications, you may want to organize themes with metadata. Theme catalogs support:

  • Active/inactive - Hide themes from production while keeping them documented
  • Tags - Categorize themes (dark, light, seasonal, test, etc.)
  • Sorting - Control display order
  • Filtering - Show only relevant themes

Catalog Structure

import type { ThemeCatalog } from 'svelte-theme-picker';

const myCatalog: ThemeCatalog = {
  'brand-dark': {
    theme: { /* theme definition */ },
    meta: {
      active: true,           // Show in picker
      tags: ['dark', 'brand'],
      order: 1,               // Sort order
      seasonal: false,        // Or 'winter', 'spring', etc.
    }
  },
  'christmas': {
    theme: { /* theme definition */ },
    meta: {
      active: false,          // Hidden from picker
      tags: ['dark', 'seasonal'],
      seasonal: 'winter',
    }
  },
  'test-theme': {
    theme: { /* theme definition */ },
    meta: {
      active: false,          // Dev only
      tags: ['test'],
    }
  },
};

Filtering Themes

import {
  defaultThemeCatalog,
  filterCatalog,
  catalogToThemes,
  getActiveThemes,
  getThemesByTag,
  getThemesByAnyTag,
} from 'svelte-theme-picker';

// Get only active themes
const activeThemes = getActiveThemes(defaultThemeCatalog);

// Get themes by tag
const darkThemes = getThemesByTag(defaultThemeCatalog, 'dark');

// Get themes by any of several tags
const accentThemes = getThemesByAnyTag(defaultThemeCatalog, ['neon', 'vibrant']);

// Advanced filtering
const productionThemes = catalogToThemes(
  filterCatalog(defaultThemeCatalog, {
    activeOnly: true,
    excludeTags: ['test', 'seasonal'],
  })
);

// Use with ThemePicker
<ThemePicker config={{ themes: productionThemes }} />

JSON-Driven Themes

Define your themes in a JSON file for easy management and version control:

themes.json

{
  "brand-dark": {
    "theme": {
      "name": "Brand Dark",
      "description": "Official dark theme",
      "colors": {
        "bgDeep": "#0a0a12",
        "bgMid": "#12121a",
        "bgCard": "#1a1a24",
        "bgGlow": "#2a2a3a",
        "bgOverlay": "#0a0a12",
        "primary1": "#6366f1",
        "primary2": "#818cf8",
        "primary3": "#a5b4fc",
        "primary4": "#c7d2fe",
        "primary5": "#e0e7ff",
        "primary6": "#eef2ff",
        "accent1": "#8b5cf6",
        "accent2": "#a78bfa",
        "accent3": "#c4b5fd",
        "textPrimary": "#f8fafc",
        "textSecondary": "#cbd5e1",
        "textMuted": "#64748b"
      },
      "fonts": {
        "heading": "'Inter', sans-serif",
        "body": "'Inter', sans-serif",
        "mono": "'JetBrains Mono', monospace"
      },
      "effects": {
        "glowColor": "rgba(99, 102, 241, 0.15)",
        "glowIntensity": 0.3,
        "particleColors": ["#6366f1", "#8b5cf6"],
        "useNoise": false,
        "noiseOpacity": 0
      }
    },
    "meta": {
      "active": true,
      "tags": ["dark", "brand", "production"],
      "order": 1
    }
  },
  "christmas-special": {
    "theme": {
      "name": "Christmas",
      "description": "Festive holiday theme"
    },
    "meta": {
      "active": false,
      "tags": ["dark", "seasonal", "holiday"],
      "seasonal": "winter"
    }
  },
  "dev-test": {
    "theme": {
      "name": "Dev Test",
      "description": "Testing theme - not for production"
    },
    "meta": {
      "active": false,
      "tags": ["test", "dev"]
    }
  }
}

Loading and filtering for production:

import {
  loadCatalogFromJSON,
  getActiveThemes,
  filterCatalog,
  catalogToThemes,
} from 'svelte-theme-picker';

// Load themes from JSON (e.g., fetched or imported)
import themesJson from './themes.json';
const catalog = loadCatalogFromJSON(themesJson);

// Get only production-ready themes (active: true)
const productionThemes = getActiveThemes(catalog);

// Or with more advanced filtering
const productionThemes = catalogToThemes(
  filterCatalog(catalog, {
    activeOnly: true,
    excludeTags: ['test', 'seasonal'],
  })
);

// Use with ThemePicker
<ThemePicker config={{ themes: productionThemes }} />

This pattern lets you:

  • Document all themes in one place (production, test, seasonal)
  • Control which themes are active in production via the active flag
  • Filter by tags for specific use cases (e.g., only dark themes)
  • Version control your theme definitions alongside your code

Catalog Utilities

// Convert simple themes to catalog
import { themesToCatalog } from 'svelte-theme-picker';
const catalog = themesToCatalog(myThemes, { active: true });

// Merge catalogs (combine default themes with your custom ones)
import { mergeCatalogs, defaultThemeCatalog } from 'svelte-theme-picker';
const combined = mergeCatalogs(defaultThemeCatalog, myCatalog);

// Get all tags in a catalog
import { getCatalogTags } from 'svelte-theme-picker';
const tags = getCatalogTags(myCatalog); // ['dark', 'brand', 'seasonal', ...]

// Sort catalog by order
import { sortCatalog } from 'svelte-theme-picker';
const sorted = sortCatalog(myCatalog);

Custom Theme Picker UI

For complete control over the theme picker UI (e.g., in forms), you can build your own using the exported utilities. This is useful when you need color swatches in a specific layout or want to match your app's design system.

Color Swatch Grid (Form Integration)

<script lang="ts">
  import {
    themeStore,
    applyTheme,
    defaultThemes,
    type Theme
  } from 'svelte-theme-picker';
  import { onMount } from 'svelte';

  let selectedTheme = $state('dreamy');

  // Revert to saved theme when leaving the page
  onMount(() => {
    return () => themeStore.revertPreview();
  });

  function previewTheme(themeId: string) {
    selectedTheme = themeId;
    themeStore.previewTheme(themeId);
    applyTheme(defaultThemes[themeId]);
  }

  function saveSelection() {
    // Persist the theme when form is submitted
    themeStore.setTheme(selectedTheme);
  }
</script>

<div class="theme-grid">
  {#each Object.entries(defaultThemes) as [id, theme]}
    <button
      type="button"
      class="theme-swatch"
      class:selected={selectedTheme === id}
      onclick={() => previewTheme(id)}
      title={theme.name}
    >
      <div class="colors">
        <span style="background: {theme.colors.primary1}"></span>
        <span style="background: {theme.colors.primary3}"></span>
        <span style="background: {theme.colors.primary5}"></span>
        <span style="background: {theme.colors.accent1}"></span>
      </div>
      <span class="name">{theme.name}</span>
    </button>
  {/each}
</div>

<style>
  .theme-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }

  .theme-swatch {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 8px;
    background: transparent;
    border: 2px solid transparent;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s;
  }

  .theme-swatch:hover {
    background: rgba(255, 255, 255, 0.05);
  }

  .theme-swatch.selected {
    border-color: var(--accent-1, #a855f7);
    background: rgba(168, 85, 247, 0.1);
  }

  .colors {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 2px;
    width: 32px;
    height: 32px;
    border-radius: 6px;
    overflow: hidden;
  }

  .colors span {
    width: 100%;
    height: 100%;
  }

  .name {
    font-size: 0.75rem;
    color: var(--text-secondary, #a0a0a0);
  }

  .theme-swatch.selected .name {
    color: var(--text-primary, #fff);
  }
</style>

Using with Forms

When integrating theme selection in a form (e.g., collection creation), use the preview pattern:

  1. On mount: Save the current theme with getPersistedThemeId()
  2. On selection: Use previewTheme() + applyTheme() for live preview
  3. On cancel/leave: Call revertPreview() to restore the original theme
  4. On save: Call setTheme() to persist the selection
<script>
  import { themeStore, applyTheme, defaultThemes } from 'svelte-theme-picker';
  import { onMount } from 'svelte';

  let selectedTheme = 'dreamy';
  let formSubmitted = false;

  onMount(() => {
    // Restore original theme if user leaves without saving
    return () => {
      if (!formSubmitted) {
        themeStore.revertPreview();
      }
    };
  });

  function selectTheme(themeId) {
    selectedTheme = themeId;
    themeStore.previewTheme(themeId);
    applyTheme(defaultThemes[themeId]);
  }

  function handleSubmit() {
    formSubmitted = true;
    themeStore.setTheme(selectedTheme);
    // ... save to database
  }
</script>

Custom Themes

You can provide your own themes:

<script>
  import { ThemePicker, type Theme } from 'svelte-theme-picker';

  const myThemes: Record<string, Theme> = {
    'my-theme': {
      name: 'My Theme',
      description: 'A custom theme',
      colors: {
        bgDeep: '#1a1a2e',
        bgMid: '#232342',
        bgCard: '#2a2a4a',
        bgGlow: '#3d3d6b',
        bgOverlay: '#1a1a2e',
        primary1: '#c9a0dc',
        primary2: '#b8a9d9',
        primary3: '#e8a4c9',
        primary4: '#7eb8da',
        primary5: '#8ad4d4',
        primary6: '#f0c4a8',
        accent1: '#a855f7',
        accent2: '#ff6b9d',
        accent3: '#64c8ff',
        textPrimary: '#e8e0f0',
        textSecondary: '#c8c0d8',
        textMuted: '#9090b0',
      },
      fonts: {
        heading: "'Inter', sans-serif",
        body: "'Inter', sans-serif",
        mono: "'JetBrains Mono', monospace",
      },
      effects: {
        glowColor: 'rgba(168, 85, 247, 0.15)',
        glowIntensity: 0.3,
        particleColors: ['#c9a0dc', '#a855f7'],
        useNoise: false,
        noiseOpacity: 0,
      },
    },
  };
</script>

<ThemePicker config={{ themes: myThemes, defaultTheme: 'my-theme' }} />

Styling the Picker

The ThemePicker component can be customized using CSS custom properties. The picker automatically uses your theme's CSS variables as fallbacks, so it adapts to your theme.

Picker CSS Properties

Override these to customize the picker appearance:

/* In your global CSS or :root */
:root {
  /* Colors */
  --stp-bg: var(--bg-card);           /* Panel background */
  --stp-bg-hover: var(--bg-glow);     /* Hover state background */
  --stp-bg-active: ...;               /* Active/selected item */
  --stp-border: ...;                  /* Border color */
  --stp-text: var(--text-primary);    /* Primary text */
  --stp-text-muted: var(--text-muted);/* Secondary text */
  --stp-accent: var(--accent-1);      /* Accent color */
  --stp-accent-glow: ...;             /* Glow effect color */

  /* Trigger button */
  --stp-trigger-bg: ...;              /* Trigger background gradient */
  --stp-trigger-color: var(--bg-deep);/* Trigger icon color */

  /* Layout */
  --stp-radius: 12px;                 /* Panel border radius */
  --stp-radius-sm: 8px;               /* Item border radius */
  --stp-space: 12px;                  /* Standard spacing */
  --stp-space-sm: 8px;                /* Small spacing */
  --stp-transition: 0.2s ease;        /* Transition timing */
}

The picker uses color-mix() for calculated colors (active states, borders) that automatically adjust to your theme. No !important overrides should be needed.

Theme Mode

Themes can declare a mode property ('light' or 'dark') to help the picker adjust its styling:

const myTheme: Theme = {
  name: 'My Light Theme',
  description: 'A light theme',
  mode: 'light',  // or 'dark'
  colors: { ... },
  fonts: { ... },
  effects: { ... },
};

CSS Variables

The theme picker applies these CSS variables to your document:

Background Colors

  • --bg-deep - Deepest background
  • --bg-mid - Mid-level background
  • --bg-card - Card/surface background
  • --bg-glow - Glow/highlight background
  • --bg-overlay - Overlay background

Primary Colors (1-6)

  • --primary-1 through --primary-6

Accent Colors (1-3)

  • --accent-1 through --accent-3

Text Colors

  • --text-primary
  • --text-secondary
  • --text-muted

Fonts

  • --font-heading
  • --font-body
  • --font-mono

Effects

  • --shadow-glow
  • --glow-color
  • --glow-intensity

Using the Store Directly

<script>
  import { themeStore, applyTheme, defaultThemes } from 'svelte-theme-picker';

  // Subscribe to changes
  $effect(() => {
    const theme = defaultThemes[$themeStore];
    if (theme) {
      console.log('Theme changed to:', theme.name);
    }
  });

  // Change theme programmatically
  function setDarkMode() {
    themeStore.setTheme('mono');
  }
</script>

Built-in Themes

| ID | Name | Tags | Description | |----|------|------|-------------| | dreamy | Dreamy | dark, pastel | Soft pastels with dreamy atmosphere | | cyberpunk | Cyberpunk | dark, neon | High contrast neons | | sunset | Sunset | dark, warm | Warm oranges and purples | | ocean | Ocean | dark, cool | Deep blues and teals | | mono | Mono | dark, minimal | Clean monochromatic | | sakura | Sakura | dark, pastel | Cherry blossom pinks | | aurora | Aurora | dark, nature | Northern lights greens and purples | | galaxy | Galaxy | dark, space | Deep space cosmic colors | | milk | Milk | light, neutral | Clean, creamy light theme | | light | Light | light, modern | Modern light theme with purple accents |

Performance

The theme picker is optimized to minimize impact on your application:

  • CSS Containment: Uses contain: layout style to isolate rendering
  • GPU Acceleration: Animations use transform and will-change for smooth 60fps transitions
  • Batched DOM Updates: Theme changes use requestAnimationFrame to batch all CSS variable updates into a single paint frame
  • Efficient Transitions: Only animates specific properties instead of transition: all
  • Minimal Bundle: ~75KB total including all 10 built-in themes

Accessibility

The component follows accessibility best practices:

  • Keyboard Navigation: Press Escape to close the theme panel
  • ARIA Labels: All interactive elements have proper aria-label attributes
  • Role Attributes: Theme list uses role="listbox" with role="option" items
  • Focus Management: Proper aria-expanded and aria-haspopup on trigger button
  • Screen Reader Support: Decorative elements marked with aria-hidden="true"

Browser Support

  • Modern browsers (Chrome, Firefox, Safari, Edge)
  • Safari: Full support including -webkit-backdrop-filter for blur effects
  • Graceful degradation: localStorage errors are handled silently (e.g., private browsing)

TypeScript

Full TypeScript support with exported types:

import type {
  // Theme types
  Theme,
  ThemeColors,
  ThemeFonts,
  ThemeEffects,
  ThemePickerConfig,
  // Catalog types
  ThemeCatalog,
  ThemeCatalogEntry,
  ThemeMeta,
  ThemeFilterOptions,
  // SSR types
  SSRConfig,
  FontConfig,
  ThemeSchema,
} from 'svelte-theme-picker';

Migration Guide

Upgrading from a previous version? See MIGRATION.md for breaking changes and migration steps.

License

MIT