Theme System
Configure web app theme presets, light/dark mode, and the default theme
Theme System
The web app uses a CSS variable-based theme system built on shadcn/ui, supporting light / dark mode and multiple preset themes.
Theme Presets
All presets are defined in:
apps/web/src/configs/theme-presets.tsEach preset contains a full set of CSS variables for both light and dark modes:
export const themePresets = {
"modern-minimal": {
label: "Modern Minimal",
styles: {
light: {
background: "#ffffff",
foreground: "#333333",
primary: "#3b82f6",
// ...
},
dark: {
background: "#171717",
foreground: "#e5e5e5",
primary: "#3b82f6",
// ...
},
},
},
// more presets...
};25 built-in presets are included: modern-minimal, violet-bloom, t3-chat, mocha-mousse, amethyst-haze, doom-64, kodama-grove, cosmic-night, and more.
Changing the Default Theme
The default theme is the first key in the themePresets object. Move the desired preset to the top of the object:
export const themePresets = {
"violet-bloom": { /* ... */ }, // ← first = default
"modern-minimal": { /* ... */ },
// ...
};If no presets exist, the app falls back to
"modern-minimal"(thefallbackThemePresetKeyinweb-config.ts).
Adding a Custom Preset
Append a new entry to the themePresets object with both light and dark variable sets:
export const themePresets = {
// existing presets...
"my-brand": {
label: "My Brand",
styles: {
light: {
background: "#fafafa",
foreground: "#111111",
primary: "#e11d48",
// ... see existing presets for full variable list
},
dark: {
background: "#0f0f0f",
foreground: "#f5f5f5",
primary: "#fb7185",
// ...
},
},
},
};The new preset will automatically appear in the theme selector UI.
User Preference Storage
User theme choices are persisted in localStorage:
| Key | Content |
|---|---|
{AppName}-ui-theme | Appearance mode: light / dark / system |
{AppName}-ui-preset | Current preset key, e.g. "modern-minimal" |
{AppName}-ui-preset-styles | Serialized CSS variables (used to prevent FOUC) |
AppName comes from the app name configured in packages/app-config.
Anti-FOUC Script
theme-config.ts exports an inline themeScript that runs in the HTML <head> before React hydrates. It applies the correct theme class and CSS variables to <html> immediately on page load, eliminating the flash of unstyled content.