Skip to main content

Themes

14 built-in color themes — pick one or build your own.

File: config/themes.config.ts

DirectoryKit has three layers of theming that stack on top of each other:

  1. Light / Dark mode — via next-themes, added as a class="dark" on the <html> tag
  2. 14 preset color themes — applied via data-color-theme="..." attribute on <html>
  3. Custom admin themes — stored in the DB, applied dynamically by SiteThemeProvider

You rarely need to touch CSS. You pick a theme and the whole app re-colors.

Built-in themes

IDVibe
defaultClean, neutral, minimalist
neo-brutalismBold primary colors, hard edges, thick shadows
amethyst-hazeSoft purple + pink pastels
bubblegumPlayful pink + teal + yellow
doom-64Gritty red + olive, low-saturation
graphiteMonochrome, light grays
mocha-mousseWarm browns + creams
monoPure monochrome, high contrast
notebookPaper-like with handwritten fonts
perpetuityTeal monospace techy
retro-arcadeNeon pink + teal + yellow
solar-duskOrange + yellow gradient
supabaseGreen + blue (matches Supabase docs)
vercelBlack + white, Vercel-inspired

How to pick a theme

Option A: change the default for all users

Edit the last line of config/themes.config.ts:

config/themes.config.ts
export const defaultColorTheme = "supabase";  // any ID from the table above

Option B: let users pick it themselves

The site ships with a theme switcher in the header. Users who pick a theme have it saved in localStorage.

Theme switcher dropdown in the site header

Option C: admins set a site-wide theme

Admins can pick and customize a theme in /admin/theme. That theme wins over the default for everyone.

Gallery of 4–6 theme previews side by side

How a theme is structured

Each theme overrides CSS variables. You only include the variables that differ from the default.

{
  id: "your-theme",
  name: "Your Theme",
  preview: ["#primary", "#secondary", "#accent", "#background"],  // shown in the picker
  light: {
    "--primary": "260 25% 57%",            // HSL values, no hsl() wrapper
    "--primary-foreground": "0 0% 100%",
    "--font-sans": "Geist, sans-serif",    // typography
    "--radius": "0.5rem",
    // ... any variable from THEME_VAR_KEYS
  },
  dark: {
    // same keys, dark-mode values
  },
}

See Theming for the full walk-through of building a custom theme from tweakcn.com.

All customizable CSS variables

Exported as THEME_VAR_KEYS:

  • Colors: background, foreground, card, card-foreground, popover, popover-foreground, primary, primary-foreground, secondary, secondary-foreground, muted, muted-foreground, accent, accent-foreground, destructive, destructive-foreground, border, input, ring, chart-1…5, sidebar, sidebar-foreground, sidebar-primary, sidebar-primary-foreground, sidebar-accent, sidebar-accent-foreground, sidebar-border, sidebar-ring
  • Typography: font-sans, font-serif, font-mono, tracking-normal
  • Shape & shadow: radius, spacing, shadow-x, shadow-y, shadow-blur, shadow-spread, shadow-opacity, shadow-color

One-line recipe

Want Supabase-style colors? Set:

export const defaultColorTheme = "supabase";

Want monochrome minimal? Set:

export const defaultColorTheme = "mono";

Let AI pick it for you

AI Prompt· Pick a theme for my brand

Look at the list of preset themes in config/themes.config.ts.

My brand:

  • Name: {brand name}
  • Vibe: {describe — e.g. "playful and pastel", "serious and corporate", "retro-gaming", "luxury editorial"}
  • Brand colors (if any): {list hex codes or say "flexible"}
  • Target audience: {who the directory is for}

Pick the single best matching theme ID and set defaultColorTheme in config/themes.config.ts. Briefly explain why you picked it. Don't create a new theme — only choose from the existing ones.