Customize Your Shadcn UI Theme Colors | Next.js Supabase SaaS Kit
Configure brand colors, dark mode, and Shadcn UI theme variables in your Makerkit application using Tailwind CSS 4.
Customize your application's color scheme by editing apps/web/styles/shadcn-ui.css. This file defines all theme variables that Shadcn UI components use, giving you complete control over your brand colors in both light and dark modes.
Quick Theme Change
The fastest way to update your theme is to use the Shadcn UI Themes page:
- Choose a color scheme on the Shadcn theme builder
- Copy the generated CSS variables
- Paste them into
apps/web/styles/shadcn-ui.css - Wrap color values with
hsl()oroklch()functions (Tailwind CSS 4 requirement)
Theme File Structure
Makerkit's theming uses three CSS files in apps/web/styles/:
| File | Purpose |
|---|---|
shadcn-ui.css | Your theme colors (edit this file) |
theme.css | Maps variables to Tailwind's theme system |
globals.css | Imports all styles and base Tailwind directives |
Core Theme Variables
Edit apps/web/styles/shadcn-ui.css to customize these color groups:
@layer base { :root { /* Font configuration */ --font-sans: -apple-system, BlinkMacSystemFont, var(--font-sans-fallback); --font-heading: var(--font-sans); /* Background and text */ --background: var(--color-white); --foreground: var(--color-neutral-950); /* Primary brand color (buttons, links, focus rings) */ --primary: var(--color-neutral-950); --primary-foreground: var(--color-white); /* Secondary actions and elements */ --secondary: oklch(96.76% 0.0013 286.38); --secondary-foreground: oklch(21.03% 0.0318 264.65); /* Muted backgrounds and text */ --muted: oklch(96.71% 0.0029 264.54); --muted-foreground: oklch(55.13% 0.0233 264.36); /* Hover states and accents */ --accent: oklch(96.76% 0.0013 286.38); --accent-foreground: oklch(21.03% 0.0318 264.65); /* Destructive actions (delete, error) */ --destructive: var(--color-red-500); --destructive-foreground: var(--color-white); /* Cards and popovers */ --card: var(--color-white); --card-foreground: var(--color-neutral-950); --popover: var(--color-white); --popover-foreground: var(--color-neutral-950); /* Borders and inputs */ --border: var(--color-gray-100); --input: var(--color-gray-200); --ring: var(--color-neutral-800); /* Border radius */ --radius: 0.5rem; /* Sidebar-specific colors */ --sidebar-background: var(--color-neutral-50); --sidebar-foreground: oklch(37.05% 0.012 285.8); --sidebar-primary: var(--color-neutral-950); --sidebar-primary-foreground: var(--color-white); --sidebar-accent: var(--color-neutral-100); --sidebar-accent-foreground: var(--color-neutral-950); --sidebar-border: var(--border); --sidebar-ring: var(--color-blue-500); /* Chart colors */ --chart-1: var(--color-orange-400); --chart-2: var(--color-teal-600); --chart-3: var(--color-green-800); --chart-4: var(--color-yellow-200); --chart-5: var(--color-orange-200); }}Dark Mode Configuration
Define dark mode colors in the .dark class within the same file:
@layer base { .dark { --background: var(--color-neutral-900); --foreground: var(--color-white); --primary: var(--color-white); --primary-foreground: var(--color-neutral-900); --secondary: var(--color-neutral-800); --secondary-foreground: oklch(98.43% 0.0017 247.84); --muted: var(--color-neutral-800); --muted-foreground: oklch(71.19% 0.0129 286.07); --accent: var(--color-neutral-800); --accent-foreground: oklch(98.48% 0 0); --destructive: var(--color-red-700); --destructive-foreground: var(--color-white); --card: var(--color-neutral-900); --card-foreground: var(--color-white); --popover: var(--color-neutral-900); --popover-foreground: var(--color-white); --border: var(--color-neutral-800); --input: var(--color-neutral-700); --ring: oklch(87.09% 0.0055 286.29); --sidebar-background: var(--color-neutral-900); --sidebar-foreground: var(--color-white); --sidebar-primary: var(--color-blue-500); --sidebar-primary-foreground: var(--color-white); --sidebar-accent: var(--color-neutral-800); --sidebar-accent-foreground: var(--color-white); }}Converting Shadcn Theme Colors to Tailwind CSS 4
Shadcn's theme builder outputs HSL values without the function wrapper. Tailwind CSS 4 requires explicit color functions.
Shadcn output:
--primary: 222.2 47.4% 11.2%;Tailwind CSS 4 format:
--primary: hsl(222.2 47.4% 11.2%);You can also use oklch() for better color perception:
--primary: oklch(21.03% 0.0318 264.65);Use any AI tool or color converter to transform the values. The key is ensuring every color value is wrapped in a color function.
Using Tailwind Color Palette
Reference Tailwind's built-in colors using CSS variables:
--primary: var(--color-blue-600);--destructive: var(--color-red-500);--accent: var(--color-indigo-100);Available color scales: slate, gray, zinc, neutral, stone, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose.
Each scale includes shades from 50 (lightest) to 950 (darkest).
Theme Mode Configuration
Control how theme switching works with these environment variables:
# Default theme: light, dark, or systemNEXT_PUBLIC_DEFAULT_THEME_MODE=system# Show/hide the theme toggle in the UINEXT_PUBLIC_ENABLE_THEME_TOGGLE=trueCustom Brand Color Example
Here's a complete example using a custom indigo brand color:
@layer base { :root { --primary: var(--color-indigo-600); --primary-foreground: var(--color-white); --secondary: var(--color-indigo-100); --secondary-foreground: var(--color-indigo-900); --accent: var(--color-indigo-50); --accent-foreground: var(--color-indigo-900); --ring: var(--color-indigo-500); } .dark { --primary: var(--color-indigo-400); --primary-foreground: var(--color-indigo-950); --secondary: var(--color-indigo-900); --secondary-foreground: var(--color-indigo-100); --accent: var(--color-indigo-800); --accent-foreground: var(--color-indigo-100); --ring: var(--color-indigo-400); }}Common Mistakes
Forgetting color function wrappers: Tailwind CSS 4 requires hsl(), oklch(), or rgb() around color values. Raw space-separated values like 222 47% 11% won't work.
Low contrast ratios: Ensure sufficient contrast between foreground and background colors. Use tools like WebAIM Contrast Checker to verify WCAG compliance.
Inconsistent dark mode: Always define dark mode variants for every color you customize. Missing dark mode variables cause jarring visual inconsistencies.
Not testing all components: Theme changes affect every Shadcn component. After updating colors, click through your app to verify buttons, inputs, cards, and dialogs all look correct.
Verification
After updating your theme:
- Start the dev server:
pnpm dev - Toggle between light and dark modes
- Check these component types:
- Primary buttons (
--primary) - Form inputs (
--input,--border,--ring) - Cards and dialogs (
--card,--popover) - Destructive actions (
--destructive) - Sidebar navigation (
--sidebar-*variables)
- Primary buttons (
Frequently Asked Questions
How do I use a custom color not in Tailwind's palette?
Why do my colors look different than the Shadcn theme preview?
Can I have different themes for different pages?
How do I disable dark mode entirely?
Next Steps
- Back to Customization Overview
- Set up your Tailwind CSS configuration for additional customizations
- Configure custom fonts for your brand typography
- Update your application logo to match your theme