Skip to main content
Cover image for Replacing DaisyUI with CSS Custom Properties

Replacing DaisyUI with CSS Custom Properties

css tailwind migration theming

I removed DaisyUI from this site. The migration reduced the CSS bundle by 27% (156KB → 114KB uncompressed) and gave me complete control over the design system.

Why I Left DaisyUI

DaisyUI added complexity for a single-theme site. The data-theme abstraction created CSS specificity battles—selectors like [data-theme=dim] .btn-primary made customization difficult. DaisyUI also hasn’t been updated for Tailwind CSS v4, which meant I’d eventually need to migrate anyway.

CSS custom properties solved both problems. No abstraction layer, no specificity issues, full control.

How I Migrated

Step 1: Define CSS Custom Properties

I defined the color palette as space-separated RGB values in src/styles/theme.css. This format enables opacity modifiers in Tailwind (bg-primary/50).

:root {
  --color-background: 23 23 23;        /* neutral-900 */
  --color-surface: 38 38 38;           /* neutral-800 */
  --color-text: 245 245 244;           /* stone-100 */
  --color-text-secondary: 168 162 158; /* stone-400 */
  --color-border: 64 64 64;            /* neutral-700 */
  --color-primary: 251 191 36;         /* amber-400 */
}

Step 2: Update Tailwind Configuration

I updated tailwind.config.js to reference the CSS variables.

colors: {
  background: 'rgb(var(--color-background) / <alpha-value>)',
  surface: 'rgb(var(--color-surface) / <alpha-value>)',
  text: 'rgb(var(--color-text) / <alpha-value>)',
  primary: 'rgb(var(--color-primary) / <alpha-value>)',
  // ... other colors
}

Step 3: Create a Custom Button System

I replaced DaisyUI’s button classes with ~50 lines of custom CSS.

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  font-weight: 500;
  border-radius: 0.25rem;
  cursor: pointer;
  transition: all 150ms ease-out;
}

.btn-primary {
  background-color: transparent;
  color: rgb(var(--color-primary));
  font-weight: 600;
}

.btn-outline {
  background-color: transparent;
  color: rgb(var(--color-text));
  position: relative;
}

/* ... etc */

Step 4: Update Components

Finally, I replaced DaisyUI’s semantic classes with explicit CSS variable classes.

<!-- Before -->
<div class="bg-base-100 text-base-content">...</div>

<!-- After -->
<div class="bg-background text-text">...</div>

What I Gained

The benefits were immediate:

  • Simplified Maintenance: Colors live in one theme.css file
  • Future-Proof: No dependency on DaisyUI for Tailwind CSS v4
  • Performance: Reduced CSS complexity and bundle size
  • Control: No more fighting framework specificity

DaisyUI is excellent for rapid prototyping and multi-theme apps. But for single-theme applications, CSS custom properties offer more control with less overhead.