Headless UI
Unstyled components from the Tailwind team.
Headless UI is a deliberately small set of accessible primitives from the Tailwind team, built to pair with Tailwind rather than to compete with the larger headless libraries.
At a glance
| Install | npm install @headlessui/react or @headlessui/vue |
| Scope | around a dozen components, not dozens |
| Styling | none, but designed around Tailwind's state variants |
| Frameworks | React and Vue |
| MCP server | not published |
| License | MIT |
Small on purpose
Menu, Listbox, Combobox, Switch, Dialog, Disclosure, Popover, Tabs, Radio Group. That is close to the whole library. Radix, Base UI and React Aria all cover far more ground.
That narrowness is the point. These are the components where accessible behaviour is genuinely hard, and Tailwind Labs built exactly those and stopped.
Why the Tailwind pairing is real
Components expose their state as data attributes, which Tailwind targets directly. Styling an open menu or a checked switch needs no render props and no conditional class logic.
import { Switch } from '@headlessui/react'
<Switch
checked={enabled}
onChange={setEnabled}
className="group h-6 w-11 rounded-full bg-gray-200 data-[checked]:bg-teal-600"
>
<span className="size-4 rounded-full bg-white transition group-data-[checked]:translate-x-5" />
</Switch>
Choose it if
- You are on Tailwind and need a handful of accessible interactive components.
- You want the smallest possible dependency for the job.
Look elsewhere if
- You need broader coverage. Base UI or React Aria go much further.
- You are not using Tailwind. The design assumes it, even though nothing enforces it.