Headless UI Components: Creating re-usable logic without thinking about design

Osman Akar

May 3, 2021·4 min read

lego island
Glen Carrie — https://unsplash.com/photos/HpMihL323k0


A headless user interface component is a component that offers maximum visual flexibility by providing no interface. This might sound like providing a user interface pattern without providing a user interface. That’s funny but true.

I will demonstrate this pattern with React but this pattern is not specific to React. It is just a pattern that helps to build reusable user interface components.

What is it?

Headless components are the components that have no user interface but have functionality. It does not care about how your components look, how they are designed, styled. It just gives you the functionality and how it will look when it is mounted or hovered is under your control. It separates the logic and behavior of a component from its visual representation.

Rule of Separation: Separate policy from mechanism; separate interfaces from engines.

— Eric S. Raymond

What is the problem?

Sometimes components are way too tied to the design they present. They are made to cater to the designs that can be found at the time of them being made but have no mindfulness of future enhancements.

Most of the time specifications and needs of a component change, by a product owner or a UX designer. Developers should have a mindset that a component might change in the future and changing the component should not take so much of their time. Otherwise, changing a component to cover new added future enhancements will be harsh and will be open to create new bugs.

Headless components cover all of these concerns by having nothing to do with the user interface and just providing functionality. When you provide stable, well-tested functionality, changing a component’s design will be a lot easier for developers.

Let’s get into an example!

The code right below is an example of a Theme component. It is just for a demonstration and it is not a headless component. It just sets the current theme of an application and displays what the current theme is.

theme component, not headless

As you can see here, the user interface and logic are coupled here. Let’s say that you want to change Set as Light and Set as Dark texts to the icon. You need to pass them as props and you need to add a couple of props to make it possible.

theme component with icon props, not headless

In the code snippet, we have added two new props, lightIcon and darkIcon. We have changed our Theme component to handle these props. If they are present, icons will be shown. Otherwise, old behavior will still work and texts will be displayed.

Let’s say that it is not enough and we have a new silly requirement which is: current theme should not be shown on some pages. That means it should be controlled by the parent component. With a new prop, showCurrentTheme.

theme component with showCurrentTheme prop, not headless

Yes, we have done it!

At the end let’s summarize what this simple silly Theme component does:

  • It displays the current theme status
  • It allows you to change the theme as light
  • It allows you to change the theme as dark
  • It allows you to hide the current theme status

With each requirement, our component will change, and let’s assume that there will be a couple of more new requirements to this component and it will be more complex. It is going to be hard to maintain and follow components by developers. Also, it can reach a point that adding new requirements is not possible without affecting an old behavior.

Headless component will rescue!

The possibilities with headless component implementation will be almost endless. You can do whatever you want with your user interface by having what is provided with a headless theme component. Let’s see how to write this component with react custom hook.

I should mention that before react hooks headless components are generally implemented with render props pattern or a higher-order component. You can search these patterns and understand how to implement headless components with these approaches. I will demonstrate it with a react custom hook.

headless component implemented with react custom hook

As you can see there is nothing related to the user interface. We have implemented a headless component with react custom hook and provided functionalities to set theme, setDark, setLight, and also provided current theme. With this approach, a developer can implement any user interface by using these functionalities. Let’s create some examples.

some examples that use theme headless component

These are some basic examples to give you an idea about how to use headless components and what they are exactly. I know it is a simple, dummy example but it covers what headless components are all about. This article is not about how to implement a theme, but it is just an example of understanding headless components. You will find a better suit in your project to implement this headless component approach.

There are great libraries that implement headless components. Like:

I suggest you take a look around the source code of these libraries, especially react-table.

If it is not enough for you, there are lots of sources about headless components. Take a look at those articles. I would suggest you read this article which is written by Merrick Christensen.