Skip to main content
While the built-in ThemeSwitcher component provides a complete solution, you may want to create a custom theme selector to match your specific design requirements. This guide shows you how to build custom selectors using the useTheme hook and theme configuration.

Prerequisites

Before building a custom selector, ensure you have:
  • Installed the theme system
  • Added the ThemeProvider to your app root
  • Installed at least one theme

Basic Custom Selector

Here’s a minimal example from the README showing how to build a custom selector:

Key Concepts

Theme Parsing

Tweakcn themes combine the theme name and mode into a single string (e.g., "catppuccin-dark"). Parse them to work with each component separately:

Independent Controls

Provide separate controls for color theme and mode:

Advanced Examples

Grid-Based Selector with Color Swatches

Tabs-Based Selector

Color Palette Selector

Show only the color swatches for a minimal design:

Using Theme Metadata

The themes-config.ts file provides rich metadata for each theme:

Available Exports

Import these from @/lib/themes-config:
ThemeConfig[]
Array of all theme configurations in the order they are defined.
ThemeConfig[]
Themes sorted alphabetically by title, with “Default” always first.
string[]
Array of theme names only: ["default", "catppuccin", "cyberpunk", ...]
string[]
All theme values including mode variants: ["default-light", "default-dark", "catppuccin-light", "catppuccin-dark", ...]
string
The default theme value: "default-dark"

ThemeConfig Interface

Best Practices

Always Include Mode Suffix

Never set a theme without the mode suffix:

Handle Hydration

Prevent hydration mismatches by checking if the component is mounted:

Preserve User Choice

When switching modes, preserve the color theme. When switching themes, preserve the mode:

Use Semantic Colors

When displaying theme colors, use the appropriate mode variant:

Filtering Themes

Show only specific categories or themes:

useTheme Hook

Learn about the useTheme hook API

ThemeSwitcher

See the built-in theme switcher component