How to Add a Theme
Learn how to create and add a new theme to your Astro Theme Switcher project. Follow these simple steps to extend the theme system.
Overview
The theme system uses semantic design tokens defined in TypeScript. Each theme consists of three files:
- • tokens.ts - Defines all design tokens (colors, typography, spacing, etc.) - You edit this
- • meta.json - Theme metadata (name, description, version) - You edit this
- • theme.css - Generated CSS custom properties (auto-generated from tokens via
npm run generate-themes) - Auto-generated, don't edit
Themes are automatically registered in the theme system and appear in the theme switcher once added.
Step-by-Step Guide
Create Theme Directory
Create a new directory in src/themes/ with your theme name (e.g., red, pink).
src/themes/
├── blue/
├── green/
├── red/ ← Your new theme
│ ├── tokens.ts
│ ├── meta.json
│ └── theme.css Define Design Tokens
Create tokens.ts with your theme's design tokens. Use semantic names (primary, surface, text.primary) rather than raw color values.
import type { DesignTokens } from '../types';
export const tokens: DesignTokens = {
color: {
primary: '#ef4444',
primaryForeground: '#ffffff',
secondary: '#fee2e2',
secondaryForeground: '#7f1d1d',
accent: '#fecaca',
accentForeground: '#7f1d1d',
background: '#fef2f2',
surface: '#fee2e2',
surfaceElevated: '#ffffff',
text: {
primary: '#7f1d1d',
secondary: '#991b1b',
muted: '#dc2626',
inverse: '#ffffff',
},
border: '#fecaca',
borderMuted: '#fee2e2',
borderStrong: '#f87171',
success: '#10b981',
successForeground: '#ffffff',
warning: '#f59e0b',
warningForeground: '#ffffff',
error: '#ef4444',
errorForeground: '#ffffff',
info: '#3b82f6',
infoForeground: '#ffffff',
hover: 'rgba(239, 68, 68, 0.1)',
active: 'rgba(239, 68, 68, 0.2)',
focus: '#ef4444',
},
typography: {
fontFamily: {
sans: 'ui-sans-serif, system-ui, ...',
serif: 'ui-serif, Georgia, ...',
mono: 'ui-monospace, SFMono-Regular, ...',
},
// ... fontSize, fontWeight, etc.
},
radius: {
sm: '0.125rem',
md: '0.375rem',
// ... more radius values
},
shadow: {
1: '0 1px 2px 0 rgb(239 68 68 / 0.1)',
// ... more shadow values
},
motion: {
duration: {
fast: '150ms',
normal: '200ms',
slow: '300ms',
},
easing: {
default: 'cubic-bezier(0.4, 0, 0.2, 1)',
// ... more easing values
},
},
};
💡 Tip: Copy an existing theme's tokens.ts file and modify the color values to match your theme.
Add Theme Metadata
Create meta.json with your theme's information.
{
"id": "red",
"name": "Red",
"description": "Bold red color scheme",
"version": "1.0.0",
"premium": false,
"tags": ["red", "bold", "energetic"]
} Generate Theme CSS
The theme.css file is automatically generated from your tokens. You don't need to write CSS manually!
npm run generate-themes This command will:
- • Read your
tokens.tsfile - • Generate
theme.csswith CSS custom properties - • Automatically create both light and dark mode variants
/* Red Theme - Light Mode */
[data-theme="red"][data-mode="light"] {
--token-color-primary: #ef4444;
--token-color-primary-foreground: #ffffff;
--token-color-background: #fef2f2;
--token-color-surface: #fee2e2;
--token-color-text-primary: #7f1d1d;
/* ... more tokens ... */
}
/* Red Theme - Dark Mode */
[data-theme="red"][data-mode="dark"] {
--token-color-primary: #f87171;
--token-color-primary-foreground: #ffffff;
--token-color-background: #7f1d1d;
--token-color-surface: #991b1b;
--token-color-text-primary: #fee2e2;
/* ... more tokens ... */
}
💡 Note: The theme.css file is auto-generated. Always edit tokens.ts and run npm run generate-themes to regenerate the CSS.
Register the Theme
Add your theme to the theme registry in src/themes/index.ts.
// Import your theme
import { tokens as redTokens } from './red/tokens';
import redMeta from './red/meta.json';
// Add to themes array
export const themes: Theme[] = [
// ... existing themes
{
meta: redMeta as ThemeMeta,
tokens: redTokens,
},
]; Import Theme CSS
Add your theme's CSS import to src/themes/themes.css.
@import './light/theme.css';
@import './dark/theme.css';
@import './blue/theme.css';
/* ... other themes ... */
@import './red/theme.css'; ← Add your theme Best Practices
Use Semantic Tokens
Always use semantic token names (primary, surface, text.primary) rather than raw color values. This ensures your theme works with all components automatically.
Ensure Contrast
Make sure text colors have sufficient contrast against their backgrounds. Use WCAG AA standards (4.5:1 for normal text, 3:1 for large text).
Test Both Modes
Each color theme should have distinct light and dark mode variants. Test both modes to ensure readability and visual appeal.
Follow Naming Conventions
Use lowercase, kebab-case for theme IDs (e.g., "red", "dark-blue"). Keep names descriptive and consistent with existing themes.
Ready to Create Your Theme?
Start by copying an existing theme and customizing it to match your brand.