# Dark Mode

Starwind UI components support light and dark themes out of the box. Dark styles use Tailwind
CSS's `dark:` variant and become active when the `dark` class is present on the `<html>` element.

Starwind's shared theme controller manages that class, persists the user's preference, follows
system color-scheme changes, and keeps theme controls synchronized.

## Add theme initialization

Render `ThemeInitScript` in your main layout's `<head>`. It applies the saved or system theme
before the page becomes visible, preventing a flash of the wrong theme.

```astro title="src/layouts/Layout.astro"
<!doctype html>
<html lang="en">
  <head>
    <!-- ... other head elements -->
    <ThemeInitScript />
  </head>
  <body>
    <slot />
  </body>
</html>
```

By default, `ThemeInitScript`:

- reads and writes the `colorTheme` key in `localStorage`;
- accepts `light`, `dark`, or `system` as the saved preference;
- uses `system` when no preference has been saved; and
- toggles the `dark` class on `<html>` based on the resolved theme.

It also reapplies the theme after Astro view transitions, so no additional
`astro:after-swap` listener is needed.

> **Info:** `system` remains the saved preference while the resolved theme follows
`window.matchMedia("(prefers-color-scheme: dark)")`. Once the shared theme controller is active,
it updates the page when the operating system preference changes.

## Customize the defaults

Pass the same settings to the initializer and any controller you initialize manually. The defaults
work for most Starwind projects.

```astro
<ThemeInitScript storageKey="colorTheme" defaultTheme="system" className="dark" />
```

| Prop | Default | Description |
| --- | --- | --- |
| `storageKey` | `"colorTheme"` | The `localStorage` key used for the saved preference. |
| `defaultTheme` | `"system"` | The preference used when no valid saved value exists. |
| `className` | `"dark"` | The class applied to `<html>` when the resolved theme is dark. |

## Add a theme control

Use Starwind UI's [Theme Toggle](/docs/components/theme-toggle/) component for a ready-to-use
light/dark control. It initializes the shared controller, updates the saved preference and `<html>`
class, and synchronizes other theme controls on the page.

```astro
---
import { ThemeToggle } from "@/components/starwind/theme-toggle";
---

<ThemeToggle ariaLabel="Toggle theme" />
```

The toggle switches between `light` and `dark`. Use the lower-level theme controller when your UI
needs an explicit three-way light, dark, and system picker or needs to change the theme
imperatively.

```ts
import { initThemeController } from "@starwind-ui/astro/theme";

const theme = initThemeController();

theme.setTheme("system");
theme.setTheme("dark");
```

> **Tip:** You can find advanced production-ready theme switchers on [Starwind Pro](https://pro.starwind.dev/components/theme-switcher/).