# DaisyUI Colors and Theming: Complete Guide to Custom Themes

> Master DaisyUI colors and theming with this comprehensive guide. Learn how DaisyUI's zero-runtime system uses CSS custom properties for instant theme switching via the data-theme attribute.

- Repository: [Pouya Saadeghi/daisyui](https://github.com/saadeghi/daisyui)
- Tags: deep-dive
- Published: 2026-07-10

---

**DaisyUI implements a zero-runtime theming system by injecting CSS custom properties into Tailwind's base layer via the [`themePlugin.js`](https://github.com/saadeghi/daisyui/blob/main/themePlugin.js) file, allowing themes to switch instantly by changing the `data-theme` attribute.**

DaisyUI is a popular Tailwind CSS component library that provides a robust theming architecture built entirely on CSS variables. Understanding how DaisyUI colors and theming work enables developers to create custom color palettes, support dark mode, and switch themes at runtime without JavaScript overhead. This guide examines the actual source code in the `saadeghi/daisyui` repository to explain how the theming engine processes configurations and generates the CSS custom properties that power your UI.

## How DaisyUI Theming Works Under the Hood

DaisyUI's theming system consists of four interconnected components that transform your [`tailwind.config.js`](https://github.com/saadeghi/daisyui/blob/main/tailwind.config.js) settings into usable CSS variables.

### Variable Mapping in variables.js

At the core of the system is [`variables.js`](https://github.com/saadeghi/daisyui/blob/main/variables.js), which exports a static object mapping semantic token names to CSS variable references. This file establishes the contract between DaisyUI's utility classes and the underlying CSS custom properties.

For example, the token `primary` maps to `var(--color-primary)`, while `base-100` maps to `var(--color-base-100)`. This abstraction allows components to reference semantic colors rather than hardcoded values.

### Theme Generation Pipeline

The [`generateThemes.js`](https://github.com/saadeghi/daisyui/blob/main/generateThemes.js) file processes your configuration's `themes` array to create a comprehensive `allThemes` object. Each theme is structured as a JavaScript object where keys match the variable map from [`variables.js`](https://github.com/saadeghi/daisyui/blob/main/variables.js).

Simultaneously, [`generateThemeFiles.js`](https://github.com/saadeghi/daisyui/blob/main/generateThemeFiles.js) creates standalone CSS files for each theme, which are used for CDN builds and static distribution.

### Plugin Injection via themePlugin.js

The critical integration happens in [`themePlugin.js`](https://github.com/saadeghi/daisyui/blob/main/themePlugin.js), which uses Tailwind's `plugin.withOptions` API. When Tailwind starts, this plugin:

1. Receives your theme configuration from [`tailwind.config.js`](https://github.com/saadeghi/daisyui/blob/main/tailwind.config.js)
2. Merges custom themes with built-in presets
3. Constructs CSS selectors targeting `:root[data-theme="name"]` and theme-controller inputs
4. Registers base styles using `addBase(baseStyles)`

The plugin generates a `baseStyles` object that maps selectors to CSS variable declarations and `color-scheme` properties. If a theme is marked as `default`, the selector includes `:where(:root)` to ensure fallback behavior.

### Runtime Activation

Users toggle themes by setting the `data-theme` attribute on the root element or using the built-in `.theme-controller` checkbox component. Because the variables are defined on the `:root` selector, they cascade naturally to all components, enabling instant theme switching without JavaScript re-renders.

## Configuring Custom Themes in tailwind.config.js

To define a custom theme, add an object to the `daisyui.themes` array in your Tailwind configuration.

```javascript
// tailwind.config.js
module.exports = {
  content: ["./src/**/*.{html,js,tsx}"],
  plugins: [require("daisyui")],
  daisyui: {
    themes: [
      {
        "my-theme": {
          primary: "#4f46e5",
          secondary: "#ec4899",
          accent: "#f59e0b",
          neutral: "#374151",
          "base-100": "#ffffff",
          "color-scheme": "dark",
        },
      },
      "light",
      "dark",
    ],
  },
}

```

Each property in your theme object corresponds to a CSS variable. The `"color-scheme"` property optionally sets the `color-scheme` CSS property for native form controls and scrollbars.

## Using Themes at Runtime

Apply themes to your application using the `data-theme` attribute or the theme-controller component.

```html
<!-- Apply theme to the entire page -->
<html data-theme="my-theme">
  <body class="bg-base-100 text-base-content">
    <button class="btn btn-primary">Primary Action</button>
    
    <!-- Theme toggle controller -->
    <input type="checkbox" class="theme-controller" value="my-theme" checked />
  </body>
</html>

```

When the `data-theme` attribute value changes, DaisyUI utilities such as `bg-primary` and `text-secondary` automatically resolve to the new theme's CSS variables.

## Implementing Dark Mode with prefers-color-scheme

DaisyUI supports automatic dark mode detection via the `prefersdark` option. When enabled in [`tailwind.config.js`](https://github.com/saadeghi/daisyui/blob/main/tailwind.config.js), the plugin injects a media query block that activates the theme when the user prefers dark mode.

```javascript
// tailwind.config.js
module.exports = {
  daisyui: {
    themes: [
      {
        "my-theme": {
          primary: "#4f46e5",
          secondary: "#ec4899",
          // ... other tokens
        },
        prefersdark: true, // Enables dark mode media query
      },
    ],
  },
}

```

This generates the following CSS in the output:

```css
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
    --color-primary: #4f46e5;
    /* Additional theme variables */
  }
}

```

The `:root:not([data-theme])` selector ensures the media query only applies when no explicit theme is set via the `data-theme` attribute.

## Referencing DaisyUI Colors in Custom CSS

Because DaisyUI defines variables on the root element, you can reference them in your own stylesheets for consistency with the active theme.

```css
.my-card {
  background-color: var(--color-base-100);
  border: 1px solid var(--color-primary);
  color: var(--color-base-content);
}

```

This approach ensures your custom components automatically adapt when users switch themes, maintaining visual consistency with DaisyUI's utility classes.

## Summary

- DaisyUI generates themes through [`variables.js`](https://github.com/saadeghi/daisyui/blob/main/variables.js), [`generateThemes.js`](https://github.com/saadeghi/daisyui/blob/main/generateThemes.js), and [`themePlugin.js`](https://github.com/saadeghi/daisyui/blob/main/themePlugin.js), creating a zero-runtime CSS variable system.
- The [`themePlugin.js`](https://github.com/saadeghi/daisyui/blob/main/themePlugin.js) file uses Tailwind's `addBase` to inject CSS custom properties into `:root` selectors based on your [`tailwind.config.js`](https://github.com/saadeghi/daisyui/blob/main/tailwind.config.js) configuration.
- Custom themes are defined as objects in the `daisyui.themes` array, mapping semantic tokens like `primary` and `base-100` to hex colors.
- Set `data-theme` attributes or use `.theme-controller` inputs to switch themes instantly without JavaScript.
- Enable `prefersdark: true` to generate `@media (prefers-color-scheme: dark)` blocks for automatic dark mode support.
- Access theme colors anywhere using `var(--color-{token})` syntax for custom CSS integration.

## Frequently Asked Questions

### How do I create a completely custom DaisyUI theme?

Define your theme as an object in the `daisyui.themes` array within [`tailwind.config.js`](https://github.com/saadeghi/daisyui/blob/main/tailwind.config.js). The object keys should match DaisyUI's semantic tokens (primary, secondary, accent, neutral, base-100, etc.) with hex color values. The theme engine in [`generateThemes.js`](https://github.com/saadeghi/daisyui/blob/main/generateThemes.js) processes these values and [`themePlugin.js`](https://github.com/saadeghi/daisyui/blob/main/themePlugin.js) injects them as CSS variables.

### Does DaisyUI support automatic dark mode detection?

Yes. Set `prefersdark: true` on your theme configuration in [`tailwind.config.js`](https://github.com/saadeghi/daisyui/blob/main/tailwind.config.js). When enabled, [`themePlugin.js`](https://github.com/saadeghi/daisyui/blob/main/themePlugin.js) generates a media query block that applies your theme variables when the user's system prefers dark mode, using the `:root:not([data-theme])` selector to avoid overriding explicit theme selections.

### How does the theme-controller component work?

The `theme-controller` is a CSS-only toggle mechanism using an `<input type="checkbox">` with the class `theme-controller`. When checked, it sets the `data-theme` attribute on the root element to the input's value. DaisyUI's generated CSS targets `[data-theme="value"]` selectors, causing the CSS variables to update instantly without JavaScript execution.

### Can I use DaisyUI color variables in my own CSS?

Yes. DaisyUI exposes all theme colors as CSS custom properties in the format `--color-{token}` (e.g., `--color-primary`, `--color-base-100`). These are defined on the `:root` selector, making them globally available. Reference them using `var(--color-primary)` in your custom stylesheets to maintain consistency with the active theme.