> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uniwind.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Themes

> Create and manage custom themes beyond light and dark in Uniwind

## Overview

While Uniwind provides `light` and `dark` themes by default, you can create unlimited custom themes for advanced use cases. Custom themes are perfect for branding variations, seasonal themes, accessibility modes, or any scenario where you need more than two color schemes.

<Info>
  Custom themes work exactly like the default themes, with full support for theme switching and CSS variable management.
</Info>

## Creating a Custom Theme

Creating a custom theme involves two steps:

1. Define theme-specific CSS variables in `global.css`
2. Register the theme in `metro.config.js`

### Step 1: Define Theme Variables in global.css

Add your custom theme using the `@variant` directive. All themes must define the same set of variables.

<Warning>
  **Important:** Every theme must define the same CSS variables. If you add a variable to one theme, add it to all themes. Uniwind will warn you in `__DEV__` mode if variables are missing.
</Warning>

#### Example: Adding a "Premium" Theme

```css global.css theme={null}
@import 'tailwindcss';
@import 'uniwind';

@layer theme {
  :root {
    /* Dark theme variables */
    @variant dark {
      --color-background: #000000;
      --color-foreground: #ffffff;
      --color-primary: #3b82f6;
      --color-card: #1f2937;
      --color-border: #374151;
    }

    /* Light theme variables */
    @variant light {
      --color-background: #ffffff;
      --color-foreground: #000000;
      --color-primary: #3b82f6;
      --color-card: #ffffff;
      --color-border: #e5e7eb;
    }

    /* Premium theme variables */
    @variant premium {
      --color-background: #1e1b4b;
      --color-foreground: #fef3c7;
      --color-primary: #fbbf24;
      --color-card: #312e81;
      --color-border: #4c1d95;
    }
  }
}
```

### Step 2: Register Theme in metro.config.js

Add your custom theme to the `extraThemes` array in your Metro configuration:

```js metro.config.js theme={null}
module.exports = withUniwindConfig(config, {
  cssEntryFile: './src/global.css',
  dtsFile: './src/uniwind-types.d.ts',
  extraThemes: ['premium'], // Register your custom theme here
});
```

<Tip>
  After adding a new theme, restart your Metro bundler for the changes to take effect.
</Tip>

### Step 3: Use Your Custom Theme

Switch to your custom theme programmatically:

```tsx  theme={null}
import { Uniwind } from 'uniwind'

// Switch to premium theme
Uniwind.setTheme('premium')
```

## Complete Example: Multiple Custom Themes

Here's a complete example with multiple custom themes for different use cases:

### global.css with Multiple Themes

```css global.css theme={null}
@import 'tailwindcss';
@import 'uniwind';

@layer theme {
  :root {
    @variant dark {
      --color-background: oklch(0.1316 0.0041 17.69);
      --color-foreground: oklch(0.98 0 0);
      --color-primary: oklch(0.6 0.2 240);
      --color-card: oklch(0.2 0.01 240);
      --color-border: oklch(0.3 0.02 240);
    }

    @variant light {
      --color-background: oklch(1 0 0);
      --color-foreground: oklch(0.2 0 0);
      --color-primary: oklch(0.5 0.2 240);
      --color-card: oklch(0.98 0 0);
      --color-border: oklch(0.9 0.01 240);
    }

    /* Ocean theme - Cool blues and teals */
    @variant ocean {
      --color-background: oklch(0.25 0.05 220);
      --color-foreground: oklch(0.95 0.02 200);
      --color-primary: oklch(0.6 0.15 200);
      --color-card: oklch(0.3 0.06 215);
      --color-border: oklch(0.4 0.08 210);
    }

    /* Sunset theme - Warm oranges and purples */
    @variant sunset {
      --color-background: oklch(0.3 0.08 30);
      --color-foreground: oklch(0.95 0.03 60);
      --color-primary: oklch(0.65 0.18 40);
      --color-card: oklch(0.35 0.1 25);
      --color-border: oklch(0.45 0.12 35);
    }

    /* Forest theme - Natural greens */
    @variant forest {
      --color-background: oklch(0.2 0.05 150);
      --color-foreground: oklch(0.95 0.02 140);
      --color-primary: oklch(0.55 0.15 145);
      --color-card: oklch(0.25 0.06 155);
      --color-border: oklch(0.35 0.08 150);
    }

    /* High Contrast theme - Accessibility focused */
    @variant high-contrast {
      --color-background: oklch(0 0 0);
      --color-foreground: oklch(1 0 0);
      --color-primary: oklch(0.7 0.25 60);
      --color-card: oklch(0.1 0 0);
      --color-border: oklch(1 0 0);
    }
  }
}
```

### metro.config.js with Multiple Themes

```js metro.config.js theme={null}
const { getDefaultConfig } = require('expo/metro-config');
const { withUniwindConfig } = require('uniwind/metro');

const config = getDefaultConfig(__dirname);

module.exports = withUniwindConfig(config, {
  cssEntryFile: './src/global.css',
  dtsFile: './src/uniwind-types.d.ts',
  extraThemes: ['ocean', 'sunset', 'forest', 'high-contrast'],
});
```

### Theme Switcher Component

Create a theme switcher that includes your custom themes:

```tsx ThemeSwitcher.tsx theme={null}
import { View, Pressable, Text, ScrollView } from 'react-native'
import { Uniwind, useUniwind } from 'uniwind'

export const ThemeSwitcher = () => {
  const { theme, hasAdaptiveThemes } = useUniwind()

  const themes = [
    { name: 'light', label: 'Light', icon: '☀️' },
    { name: 'dark', label: 'Dark', icon: '🌙' },
    { name: 'ocean', label: 'Ocean', icon: '🌊' },
    { name: 'sunset', label: 'Sunset', icon: '🌅' },
    { name: 'forest', label: 'Forest', icon: '🌲' },
    { name: 'high-contrast', label: 'High Contrast', icon: '♿' },
  ]
  const activeTheme = hasAdaptiveThemes ? 'system' : theme

  return (
    <View className="p-4 gap-4">
      <Text className="text-sm text-foreground">
        Current: {activeTheme}
      </Text>

      <ScrollView horizontal showsHorizontalScrollIndicator={false}>
        <View className="flex-row gap-2">
          {themes.map((t) => (
            <Pressable
              key={t.name}
              onPress={() => Uniwind.setTheme(t.name)}
              className={`
                px-4 py-3 rounded-lg items-center
                ${activeTheme === t.name ? 'bg-primary' : 'bg-card border border-border'}
              `}
            >
              <Text className={`text-2xl ${activeTheme === t.name ? 'text-white' : 'text-foreground'}`}>
                {t.icon}
              </Text>
              <Text className={`text-xs mt-1 ${activeTheme === t.name ? 'text-white' : 'text-foreground'}`}>
                {t.label}
              </Text>
            </Pressable>
          ))}
        </View>
      </ScrollView>
    </View>
  )
}
```

## Best Practices

<Tip>
  **Keep variable names consistent:** Use the same variable names across all themes. This ensures components look correct regardless of the active theme.
</Tip>

<Tip>
  **Test all themes:** Always test your UI with every theme to ensure proper contrast and readability.
</Tip>

<Tip>
  **Use OKLCH for better colors:** Consider using OKLCH color space for more perceptually uniform themes. See the [Global CSS](/theming/global-css) guide for details.
</Tip>

<Warning>
  **Don't forget to restart Metro:** Changes to `metro.config.js` require a Metro bundler restart to take effect.
</Warning>

## Troubleshooting

### Theme not appearing

1. Check that the theme is registered in `extraThemes` array
2. Verify all CSS variables are defined in the `@variant`
3. Restart Metro bundler
4. Clear Metro cache: `npx expo start --clear`

### Missing styles

1. Ensure all themes define the same set of CSS variables
2. Check for typos in variable names
3. Look for warnings in `__DEV__` mode about missing variables

## Related

<CardGroup cols={2}>
  <Card title="Theming Basics" icon="palette" href="/theming/basics">
    Learn the fundamentals of theming in Uniwind
  </Card>

  <Card title="Global CSS" icon="css" href="/theming/global-css">
    Configure global styles and CSS variables
  </Card>

  <Card title="Update CSS Variables" icon="wand-magic-sparkles" href="/theming/update-css-variables">
    Dynamically update CSS variables at runtime
  </Card>

  <Card title="useUniwind Hook" icon="code" href="/api/use-uniwind">
    Access theme information in your React components
  </Card>

  <Card title="Style Based on Themes" icon="paintbrush" href="/theming/style-based-on-themes">
    Advanced theme-based styling techniques
  </Card>
</CardGroup>
