Language: JavaScript
UI Framework
Headless UI was created by the Tailwind Labs team to complement Tailwind CSS. While Tailwind provides utility-first styling, Headless UI provides behavior and accessibility primitives (like modals, menus, and listboxes) without enforcing a specific design. This separation of concerns allows developers to build custom UIs quickly while ensuring accessibility standards.
Headless UI is a set of completely unstyled, accessible UI components for React and Vue. It provides the functionality and accessibility features, leaving styling fully up to you.
npm install @headlessui/reactyarn add @headlessui/reactHeadless UI does not provide a CDN build; install via npm or yarn.Install via npm/yarn and import only the required components into your React/Vue project.Headless UI provides fully accessible interactive components such as Dialog, Menu, Listbox, Tabs, and Transition. These components are unstyled by default, so you can apply any styling framework (commonly Tailwind CSS) or custom CSS.
import { Dialog } from '@headlessui/react';
function MyModal({ isOpen, onClose }) {
return (
<Dialog open={isOpen} onClose={onClose}>
<Dialog.Panel className="p-4 bg-white rounded">
<Dialog.Title>My Modal</Dialog.Title>
<Dialog.Description>This is a headless modal.</Dialog.Description>
<button onClick={onClose}>Close</button>
</Dialog.Panel>
</Dialog>
);
}Renders an accessible modal dialog with a title, description, and close button. Styling is fully customizable.
import { Menu } from '@headlessui/react';
<Menu>
<Menu.Button>Options</Menu.Button>
<Menu.Items>
<Menu.Item><button>Edit</button></Menu.Item>
<Menu.Item><button>Delete</button></Menu.Item>
</Menu.Items>
</Menu>Creates an accessible dropdown menu with two options. You can style the button and items as desired.
import { Listbox } from '@headlessui/react';
const people = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
function MyListbox() {
const [selected, setSelected] = React.useState(people[0]);
return (
<Listbox value={selected} onChange={setSelected}>
<Listbox.Button>{selected.name}</Listbox.Button>
<Listbox.Options>
{people.map(person => (
<Listbox.Option key={person.id} value={person}>
{person.name}
</Listbox.Option>
))}
</Listbox.Options>
</Listbox>
);
}Implements a fully accessible select dropdown using Listbox, with state management for the selected option.
import { Tab } from '@headlessui/react';
function MyTabs() {
return (
<Tab.Group>
<Tab.List>
<Tab>Tab 1</Tab>
<Tab>Tab 2</Tab>
</Tab.List>
<Tab.Panels>
<Tab.Panel>Content 1</Tab.Panel>
<Tab.Panel>Content 2</Tab.Panel>
</Tab.Panels>
</Tab.Group>
);
}Creates a tabbed interface with accessible keyboard navigation and ARIA roles managed automatically.
Pair Headless UI with Tailwind CSS or your preferred styling system for fast UI development.
Leverage Headless UI components when you need accessibility guarantees without prebuilt styles.
Use Transition component for smooth animations with modals, menus, and dropdowns.
Keep accessibility in mind — Headless UI already manages ARIA roles, focus, and keyboard navigation.
Compose small, reusable UI primitives to match your design system.