Headless UI - a great components library for Vue & React
Tags: vue, react, javascript, typescript
Published: 2024-03-25 08:41:41

Since I started my career as a developer, I was always struggling with UI component libraries that come with their own design systems like Vuetify, Material Design, and similar. Don't get me wrong, these libraries can help you accelerate development by a mile but you have to keep into consideration that at certain point of the project development you may run into a case where you will have to create workaround on top of a workaround to make certain things work (especially in temrs of styling).

And I am not a fan of that. When choosing a UI components library, I would have to find the best match - get the best out of two worlds:

1. Accelerate development speed
2. Do not need to create workarounds later on to make things work

And that is why I was looking for a UI library that would deliver these things for a long time and today I am happy to announce that I have found it! It is [Headless UI](https://headlessui.com/) by the Tailwind Team.

This UI library delivers exactly what I need - a UI components that are unstyled and they just work, while I can deliver all the styling that my design needs. 

## 🤔 What are Headless UI?

As the description states:

```
Headless UI is a completely unstyled, fully accessible UI components, designed to integrate beautifully with Tailwind CSS.
```

It comes with several production ready components that are unstyled and just work (not to mention that they are accessible as well)

![Headless UI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xvbq06f8ek5kvgo4uajh.png)

It may not sound that impressive if you compare Headless UI with a library like Vuetify that has 50 something components but believe me, Headless UI will give you tools to build your own component library while accelerating the development of the complex components like radio, autocomplete, modals, and more.

Keep in mind that each of these components can be customized by using props to deliver just the functionality you need and looking at the very detailed documentation of each of these components, I managed to build several different components out of one headless ui component. And they work perfectly with TailwindCSS which for me is the go to solution for building modern web apps.

## 🟢 Using Headless UI with your favorite framework

For me, it will obviously be Vue but the process for React is very similar ;)

The usage is really straightforward - we just need to install the package like following:

```bash
npm install @headlessui/vue
```

And we can start using the components right away:

```vue
<template>
  <Switch
    v-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>
</template>

<script setup>
  import { ref } from 'vue'
  import { Switch } from '@headlessui/vue'

  const enabled = ref(false)
</script>
```

What I especially like about Headless UI that it does not create their own interface or approach to building components. It uses the regular framework approach like in this case usage of Vue refs so that a Vue developer can easily get started with it.

The next documentation sections will guide you through the process of styling certain states or using more components from the library like so:

```vue
<template>
  <SwitchGroup>
    <div class="flex items-center">
      <SwitchLabel class="mr-4">Enable notifications</SwitchLabel>
      <Switch
        v-model="enabled"
        :class='enabled ? "bg-blue-600" : "bg-gray-200"'
        class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
      >
        <span
          :class='enabled ? "translate-x-6" : "translate-x-1"'
          class="inline-block h-4 w-4 transform rounded-full bg-white transition-transform"
        />
      </Switch>
    </div>
  </SwitchGroup>
</template>

<script setup>
  import { ref } from 'vue'
  import { Switch, SwitchGroup, SwitchLabel } from '@headlessui/vue'

  const enabled = ref(false)
</script>
```

In the example above, we used `SwitchGroup` and `SwitchLabel` components apart from the regular `Switch` component to achieve a functionality that we desire.

What is also really important for me is the fact that Headless UI cares about Accessibility. Because of that, for each component you will get a `Accessibility notes` where you can see all the recommended concepts for making your components more accessible.

## 🖥️ How do we use Headless UI at Alokai?

At [Alokai](https://alokai.com/) we use Headless UI in few projects namely:

1. [Storefront UI](https://alokai.com/product/storefront-ui) -> A UI Components library built specifically for E-Commerce applications that follow similar patters as Headless UI
2. [Console](https://alokai.com/product/console) -> A hosting platform for e-commerce applications

And we are really happy to be using Headless UI. It allowed us to accelerate development of both our UI library and the Console as well as avoid being vendor locked in to a design system as Headless UI allows you to build your own component library 🚀

## 📖 Learn more 

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this [link](https://vueschool.io/courses?friend=baroshem) or by clicking the image below:

[![Vue School Link](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i662jpyni4zs2dlaeud1.png)](https://vueschool.io/courses?friend=baroshem)

It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

## ✅ Summary

Well done! You have just learned about the Headless UI Component library and how it can help build you next app. 

Take care and see you next time!

And happy coding as always 🖥️