Convert Figma logo to code with AI

tailwindlabs logoheadlessui

Completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.

25,656
1,055
25,656
54

Top Related Projects

27,910

A rugged, minimal framework for composing JavaScript behavior in your markup.

207,677

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core

227,213

The library for web and native user interfaces.

36,546

⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.

78,194

Cybernetically enhanced web apps

18,486

Lit is a simple library for building fast, lightweight web components.

Quick Overview

Headless UI is a set of completely unstyled, fully accessible UI components for React, Vue, and Alpine.js. It provides the functionality and accessibility of common UI elements without any pre-defined styles, allowing developers to implement their own custom designs easily.

Pros

  • Fully accessible components out of the box
  • Framework-agnostic, supporting React, Vue, and Alpine.js
  • Highly customizable with no pre-defined styles
  • Lightweight and focused on core functionality

Cons

  • Requires more initial setup and styling compared to pre-styled component libraries
  • Limited number of components compared to some other UI libraries
  • Learning curve for developers used to pre-styled components
  • May require additional effort to ensure consistent styling across projects

Code Examples

  1. Using a Headless UI Dropdown in React:
import { Menu } from '@headlessui/react'

function MyDropdown() {
  return (
    <Menu>
      <Menu.Button>Options</Menu.Button>
      <Menu.Items>
        <Menu.Item>
          {({ active }) => (
            <a
              className={`${active && 'bg-blue-500'}`}
              href="/account-settings"
            >
              Account settings
            </a>
          )}
        </Menu.Item>
        <Menu.Item>
          {({ active }) => (
            <a
              className={`${active && 'bg-blue-500'}`}
              href="/logout"
            >
              Logout
            </a>
          )}
        </Menu.Item>
      </Menu.Items>
    </Menu>
  )
}
  1. Using a Headless UI Dialog (Modal) in Vue:
<template>
  <Dialog :open="isOpen" @close="closeModal">
    <DialogPanel>
      <DialogTitle>Deactivate account</DialogTitle>
      <DialogDescription>
        Are you sure you want to deactivate your account? All of your data will be permanently removed.
      </DialogDescription>
      <button @click="closeModal">Cancel</button>
      <button @click="deactivateAccount">Deactivate</button>
    </DialogPanel>
  </Dialog>
</template>

<script>
import { ref } from 'vue'
import { Dialog, DialogPanel, DialogTitle, DialogDescription } from '@headlessui/vue'

export default {
  components: { Dialog, DialogPanel, DialogTitle, DialogDescription },
  setup() {
    const isOpen = ref(false)
    // ... rest of the component logic
  }
}
</script>
  1. Using a Headless UI Switch in Alpine.js:
<div x-data="{ enabled: false }">
  <Switch
    x-model="enabled"
    :class="enabled ? 'bg-blue-600' : 'bg-gray-200'"
    class="relative inline-flex h-6 w-11 items-center rounded-full"
  >
    <span class="sr-only">Enable notifications</span>
    <span
      :class="enabled ? 'translate-x-6' : 'translate-x-1'"
      class="inline-block h-4 w-4 transform rounded-full bg-white transition"
    />
  </Switch>
</div>

Getting Started

To get started with Headless UI, first install the package for your framework:

For React:

npm install @headlessui/react

For Vue:

npm install @headlessui/vue

For Alpine.js:

npm install @headlessui/alpine

Then, import and use the components in your project as shown in the code examples above. Remember to style the components according to your design requirements.

Competitor Comparisons

27,910

A rugged, minimal framework for composing JavaScript behavior in your markup.

Pros of Alpine

  • Lightweight and minimal, with a smaller learning curve
  • Can be used without a build step, making it easier to integrate into existing projects
  • More flexible and can be used for a wider range of UI interactions beyond just components

Cons of Alpine

  • Less structured approach to building complex UI components
  • Lacks built-in accessibility features and ARIA support
  • May require more manual work for consistent styling across components

Code Comparison

Alpine:

<div x-data="{ open: false }">
    <button @click="open = !open">Toggle</button>
    <div x-show="open">Content</div>
</div>

Headless UI:

import { Disclosure } from '@headlessui/react'

function MyDisclosure() {
  return (
    <Disclosure>
      <Disclosure.Button>Toggle</Disclosure.Button>
      <Disclosure.Panel>Content</Disclosure.Panel>
    </Disclosure>
  )
}

Summary

Alpine is a lightweight JavaScript framework for adding interactivity to web pages, while Headless UI is a set of unstyled, fully accessible UI components. Alpine offers more flexibility and ease of integration, but Headless UI provides a more structured approach to building complex, accessible components. The choice between them depends on project requirements, team expertise, and the desired level of control over component behavior and accessibility.

207,677

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core

Pros of Vue

  • Full-featured framework with comprehensive ecosystem
  • Gentle learning curve and excellent documentation
  • Flexible and scalable for both small and large applications

Cons of Vue

  • Larger bundle size compared to Headless UI
  • More opinionated structure, potentially less flexibility for UI components
  • May be overkill for projects only needing basic UI components

Code Comparison

Vue component example:

<template>
  <button @click="count++">Count is: {{ count }}</button>
</template>

<script>
export default {
  data() {
    return { count: 0 }
  }
}
</script>

Headless UI component example:

import { useState } from 'react'
import { Menu } from '@headlessui/react'

function MyDropdown() {
  return (
    <Menu>
      <Menu.Button>Options</Menu.Button>
      <Menu.Items>
        <Menu.Item>
          {({ active }) => (
            <a className={`${active && 'bg-blue-500'}`} href="/account">
              Account
            </a>
          )}
        </Menu.Item>
      </Menu.Items>
    </Menu>
  )
}

Vue provides a more complete framework with built-in state management and templating, while Headless UI focuses on providing unstyled, accessible UI components that can be easily customized.

227,213

The library for web and native user interfaces.

Pros of React

  • Larger ecosystem and community support
  • More comprehensive, handling entire UI development
  • Wider range of use cases and applications

Cons of React

  • Steeper learning curve for beginners
  • Heavier bundle size, potentially impacting performance
  • More opinionated about overall application structure

Code Comparison

React component:

function Button({ onClick, children }) {
  return <button onClick={onClick}>{children}</button>;
}

Headless UI component:

import { Button } from '@headlessui/react'

function MyButton({ onClick, children }) {
  return (
    <Button onClick={onClick}>
      {children}
    </Button>
  )
}

Key Differences

  • React is a full-fledged UI library, while Headless UI focuses on unstyled, accessible components
  • Headless UI is built on top of React, providing a more specialized toolset
  • React requires more setup and configuration, whereas Headless UI offers ready-to-use components
  • Headless UI emphasizes accessibility and customization, while React provides a broader foundation

Use Cases

  • Choose React for building complex, full-scale applications
  • Opt for Headless UI when prioritizing accessibility and design flexibility in React projects
36,546

⚛️ Fast 3kB React alternative with the same modern API. Components & Virtual DOM.

Pros of Preact

  • Smaller bundle size and faster performance
  • Compatible with React ecosystem
  • Simpler API and easier learning curve

Cons of Preact

  • Less extensive component library compared to Headless UI
  • Fewer accessibility features out-of-the-box
  • May require additional setup for advanced React features

Code Comparison

Preact:

import { h, render } from 'preact';

const App = () => <h1>Hello, World!</h1>;

render(<App />, document.body);

Headless UI:

import { Menu } from '@headlessui/react'

function MyDropdown() {
  return (
    <Menu>
      <Menu.Button>Options</Menu.Button>
      <Menu.Items>
        <Menu.Item>
          {({ active }) => (
            <a className={`${active && 'bg-blue-500'}`} href="/account">
              Account
            </a>
          )}
        </Menu.Item>
      </Menu.Items>
    </Menu>
  )
}

Preact focuses on providing a lightweight alternative to React with a similar API, while Headless UI offers unstyled, fully accessible UI components. Preact is ideal for projects prioritizing performance and small bundle sizes, whereas Headless UI is better suited for applications requiring robust, accessible UI components with full styling control.

78,194

Cybernetically enhanced web apps

Pros of Svelte

  • Offers a complete framework for building web applications, not just UI components
  • Compiles to highly efficient vanilla JavaScript, resulting in smaller bundle sizes
  • Provides a simpler, more intuitive syntax with less boilerplate code

Cons of Svelte

  • Smaller ecosystem and community compared to React-based solutions like Headless UI
  • Less flexibility in terms of integration with other libraries or frameworks
  • Steeper learning curve for developers already familiar with React or Vue

Code Comparison

Svelte component:

<script>
  export let name = 'World';
</script>

<h1>Hello {name}!</h1>

Headless UI component (React):

import { Menu } from '@headlessui/react'

function MyDropdown() {
  return (
    <Menu>
      <Menu.Button>Options</Menu.Button>
      <Menu.Items>
        <Menu.Item>
          {({ active }) => (
            <a className={`${active && 'bg-blue-500'}`} href="/account-settings">
              Account settings
            </a>
          )}
        </Menu.Item>
      </Menu.Items>
    </Menu>
  )
}

The code comparison showcases Svelte's simplicity in component creation, while Headless UI demonstrates its focus on providing accessible, unstyled components for React applications.

18,486

Lit is a simple library for building fast, lightweight web components.

Pros of Lit

  • Framework-agnostic: Works with any frontend framework or vanilla JavaScript
  • Lightweight and fast: Smaller bundle size and better performance
  • Web Components: Creates reusable custom elements that work across different frameworks

Cons of Lit

  • Less opinionated: Requires more setup and configuration for complex UI components
  • Smaller ecosystem: Fewer pre-built components and community resources compared to Headless UI

Code Comparison

Headless UI (React):

import { Menu } from '@headlessui/react'

function MyDropdown() {
  return (
    <Menu>
      <Menu.Button>Options</Menu.Button>
      <Menu.Items>
        <Menu.Item>
          {({ active }) => (
            <a className={`${active && 'bg-blue-500'}`} href="/account">
              Account
            </a>
          )}
        </Menu.Item>
      </Menu.Items>
    </Menu>
  )
}

Lit:

import { LitElement, html } from 'lit'

class MyDropdown extends LitElement {
  render() {
    return html`
      <button @click=${this._toggleMenu}>Options</button>
      <ul ?hidden=${!this.menuOpen}>
        <li><a href="/account">Account</a></li>
      </ul>
    `
  }
}
customElements.define('my-dropdown', MyDropdown)

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Headless UI

A set of completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.


Documentation

For full documentation, visit headlessui.com.

Installing the latest version

You can install the latest version by using:

  • npm install @headlessui/react@latest
  • npm install @headlessui/vue@latest

Installing the insiders version

You can install the insiders version (which points to whatever the latest commit on the main branch is) by using:

  • npm install @headlessui/react@insiders
  • npm install @headlessui/vue@insiders

Note: The insiders build doesn't follow semver and therefore doesn't guarantee that the APIs will be the same once they are released.

Packages

NameVersionDownloads
@headlessui/reactnpm versionnpm downloads
@headlessui/vuenpm versionnpm downloads
@headlessui/tailwindcssnpm versionnpm downloads

Community

For help, discussion about best practices, or any other conversation that would benefit from being searchable:

Discuss Headless UI on GitHub

For casual chit-chat with others using the library:

Join the Tailwind CSS Discord Server

Contributing

If you're interested in contributing to Headless UI, please read our contributing docs before submitting a pull request.

NPM DownloadsLast 30 Days