UI libraries for Tailwind users: lessons learned

David Dahan
May 2023 ● 4 min

Ever since I discovered Tailwind CSS, I have been in love with it and abandoned the notion of using pure CSS. Tailwind CSS allows me to have granular control over my styling in an effortless manner, and it feels like the perfect level of abstraction for me. For the first time, I feel capable of creating my own UI components using this framework.

However, there comes a point in any project where having pre-built UI components is essential to save time. For projects where the UI is not the primary focus, it may not be worth the effort to build every component from scratch.

My journey to find the right tools for this has been a little chaotic thus far. In this article, I'll explain why in detail, how I currently choose the appropriate tool for the job, and why a particular library could change everything in the future.

First, here are the main issues I encountered.

πŸ˜• Built-in styles does not necessarily mean time saving

When I first discovered Ionic Framework (before Tailwind existed), I was amazed to have access to high-quality components for free. However, over time, I began to feel increasingly confined by the existing styling. Whenever I wanted to make a simple modification, I had to understand how the component was built and how to change its style, which was often done in an inconsistent manner. Even something as basic as adjusting the padding or margin could be a mess. Furthermore, after a few days, it became challenging to distinguish between my custom styling and the pre-existing styles. I found myself spending an excessive amount of time in the Chrome inspector, and the overall developer experience was poor. In summary, it's important to note that using external components that you don't control is not a guaranteed time-saver.

πŸ˜• The component I need does not exist

At some point in a project, I inevitably require an additional component that does not exist, regardless of the library I'm using. And, of course, it's often a complex one since the basics are already covered. This is where I feel like I've hit a wall, and regret not having learned how to build things from scratch. At this point, the issue is that I feel completely unprepared to build a complex component myself since I haven't even attempted to build a simple one.

πŸ˜• Lib A does X, Lib B does Y, but I want both X and Y in a single library

  • Daisy UI has decent amount of components, is easy to customize with tailwind…but it's pure CSS and lacks the logic necessary for more complex components, as it's not tied to any front-end framework.
  • Headless UI was created with React/Vue front-ends in mind and provides unstyled components. But there are so few components available that it's almost certain I'll need something else (see the issue of needing a component that doesn't exist).
  • Tailwind UI has a wide variety of built-in components and front-end examples, but the styling is highly opinionated. Unless I decide to use their exact theme, I will likely have to spend time fighting against existing styles to override them with my own. In my experience, sites like Tailwind UI are more helpful for finding inspiration rather than providing usable components.
  • PrimeVue (or PrimeReact, PrimeNg for other front-end frameworks) has an impressive collection of high-quality components that integrate perfectly with front-end frameworks. However, it's worth noting that it's not designed to be used with Tailwind, and custom styling can be frustrating.

So, what to choose in the end?

As usual in tech land, we need to make compromises, and the decision depends on the project needs.

πŸ‘‰ If the project needs a few simple components I go all-in for Do It Yourself. For example, this small website has no UI lib: I'm using simple buttons, badges, cards, and toasts, with a little Vue simple logic. I built them very quickly.

πŸ‘‰ If my primary goal is to learn and I have plenty of time I stick to the Do It Yourself philosophy. For complex components, I take a look to the source code of PrimeVue components, to try to understand and build my own one then.

πŸ‘‰ If the project is a big one with time constraints In that case, and especially if there is no specific design requirements (like a back office), I pick the library that gives me the more components I could ever need, to maximise the chances it's self-sufficient. I should be able to quickly develop a consistent UI, and I won't struggle with custom styling.

πŸ™ PrimeVue may become the all-in-one solution I've been waiting for

Rencently, I came across a PrimeVue announcement that got me very excited. To understand why it's such a big deal, you need to understand their theming architecture first. Rather than hard coding styles like Tailwind UI, styling has been separated into two parts, core and theme:


This is clever because it gives you the best of both worlds: the ability to write your own styles, without having to style everything by yourself. The image example speaks for itself. And thanks to this architecture, they will be able to provide an unstyled mode to write custom styles using only Tailwind classes.

So, in a near future, I will probably get everything I can expect from a UI lib :

  • Plenty of UI components, with the ability to make my own if there is a need for more, by examining the source code.
  • A deep integration with my front-end framework to have both UI and logic built in those components.
  • Clever styling with "semi-styled" components that will allow me to avoid styling every component entirely. Instead, I'll provide generic rules that apply to multiple components.
  • 100% Tailwind styling, no CSS to read or write.

Finger crossed 🀞

written by
David Dahan