# Theme toggle (goodtabs UI)

Switches the html dark class and remembers the choice, with no theme library.

## Install

```bash
npx shadcn@latest add https://ui.goodtabs.co/r/theme-toggle.json
```

Or, with the @goodtabs namespace configured in components.json: `npx shadcn@latest add @goodtabs/theme-toggle`

## Usage

```tsx
import { ThemeToggle } from "@/components/ui/theme-toggle"

<ThemeToggle />
<ThemeToggle variant="outline" size="icon-sm" />
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| variant | `Button variant` | `"ghost"` | Any shadcn button variant. Ghost for headers, outline on its own. |
| size | `Button size` | `"icon"` | Any icon size: icon is 32px, icon-sm 28px, icon-xs 24px. |

## When to use

- In the header or footer of a site that has a light and a dark theme
- In a settings row or command menu as the one place to switch
- When you do not want a theme library for a single toggle

## When not to use

- For a third system option; this is a two-state switch
- When the theme is set per user on the server; wire the choice to your own store instead
- If the site has no dark theme yet; add the dark tokens first

## Notes for agents

- It toggles the dark class on html and writes light or dark to localStorage under the key theme; add a small inline script in the head that reads that key before paint to avoid a flash
- It renders a neutral icon and the label Switch theme until mounted, then reads the html class, so there is no hydration mismatch
- On goodtabs.co next-themes reads the same key and class, so both stay in sync; a next-themes toggle on the same page keeps working
- It watches the html class, so a theme set from anywhere else on the page updates the icon and label

Docs: https://ui.goodtabs.co/components/theme-toggle