Theming
Pick a preset theme or design your own.
DirectoryKit stacks three theming systems. Each is independent — you can use one, two, or all three.
| Layer | Controlled by | Changed via |
|---|---|---|
| Light / Dark mode | next-themes | Sun/moon toggle in header |
| Color theme | config/themes.config.ts | defaultColorTheme or user picker |
| Custom admin theme | site_settings table | /admin/theme |
The quick path — pick a preset
Edit the last line of config/themes.config.ts:
export const defaultColorTheme = "supabase"; // pick any ID from the presetsSee all presets in Themes Config.
Theme gallery

Let users pick
The header ships with a theme picker. Users who pick a theme have their choice saved in localStorage — next visit, same theme.

How themes work under the hood
- Every color is a CSS variable defined in
app/globals.css - Colors are stored as raw HSL (e.g.
"260 22% 57%") — nohsl()wrapper - In Tailwind you use
hsl(var(--primary)) - Themes override a subset of variables via the
data-color-themeattribute on<html>
Example of a minimal theme override:
{
id: "ocean",
name: "Ocean",
preview: ["#0d9488", "#5eead4", "#ccfbf1", "#e6fffa"],
light: {
"--primary": "184 92% 29%",
"--primary-foreground": "0 0% 100%",
"--background": "180 21% 93%",
"--font-sans": "Inter, sans-serif",
"--radius": "0.5rem",
},
dark: {
"--primary": "180 77% 60%",
"--background": "196 52% 8%",
},
}You only override what differs from the default. Missing variables fall back to :root / .dark in globals.css.
Build a custom theme from tweakcn.com
The fastest way to a new theme is tweakcn.com/editor/theme:
- Open tweakcn, pick a preset or adjust sliders until you like it
- Click Code → select Tailwind v3 (HSL)
- Copy the values for
:root(light) and.dark - Paste into a new entry in
config/themes.config.ts - Set
defaultColorThemeto the new ID (or let users pick it)
Admin custom themes
Admins at /admin/theme can:
- Open any preset and tweak values live
- Save as the site-wide theme (applies to all users, beats the config default)
- Adjust fonts, border radius, shadows, spacing — not just colors
The custom theme is stored in the site_settings table and loaded by SiteThemeProvider on every render.
Typography
Fonts are config-driven via the --font-sans, --font-serif, --font-mono CSS variables in your theme. To change the site-wide default without making a new theme, edit app/globals.css or overwrite in the default theme entry.
For Google Fonts, also import in app/layout.tsx.
When changes don't show up
- Restart the dev server if you changed CSS variable values in
globals.css - Hot-reload handles changes inside
themes.config.ts - Admin theme changes in
/admin/themepush live via DB — refresh the page