Moving away from imperative libraries (jQuery) to declarative component-based frameworks (React, Vue) has paved the way for headless UI components.
Traditional UI component libraries like Select2 or Pikaday render a custom <select>
or date picker for you. If you want to customize them, they probably have some form of configuration object and event-based API. If you want to change their styling, you can dig into the implementation details and throw a bunch of !important
s in the mix to brute force your design language on them. Don't get us wrong, Select2 and Pikaday are still a joy to work with when they're the right fit, but if you need to stray off the beaten path things can get ugly.
Fast-forward to having React, Vue, or any other component-based framework at our disposal and a new pattern has emerged: headless components. Headless or renderless components started picking up steam when Kent C. Dodds released downshift as an instant hit in 2017. Downshift contains a set of primitive components to build your custom dropdown or dropdown-adjacent component (autocompletes, comboboxes, etc.) "Primitive" means downshift will render accessible HTML and bind the necessary event listeners, but it's up to you to compose them as needed and style everything from scratch.
Downshift paved the way for entire libraries built around this concept. Radix Primitives is currently leading the pack. "Unstyled, accessible, open source React primitives for high-quality web apps and design systems." Radix's API is highly composable and lets you build dropdown menus, modals, tabs, and all that jazz in the exact shape your app needs.
The downside of having all this control is it's way more setup than calling $('select').select2()
. Enter shadcn/ui. "This is NOT a component library. It's a collection of re-usable components that you can copy and paste into your apps." Shadcn is essentially a generator for Radix components with Tailwind. It's a great way to kickstart a project as you can slowly migrate the defaults away and customize it into your own. As you take ownership of the generated components, you can mould them as required.
Not a React developer? Radix and shadcn/ui have become so popular in React that the Vue and Svelte ecosystem have their mirrors: radix-vue, shadcn-vue, and shadcn-svelte. Not using a frontend framework? If you're a Laravel developer you're in luck, Caleb Porzio's recently released Flux framework follows the same design philosophy as Radix and is a great place to start building a Laravel app.