Jan 13, 2023

I Built a Component Library

In the past few months, I've prototyped several toy projects to explore ideas, learn new things, etc. Having a well-thought-out project starter is one of the crucial parts of being able to quickly build something and test out an idea. While I have a pretty solid project starter, one thing that always slowed me down is a collection of React components that I can use in my prototypes.

Why build a component library in 2023, when there are plenty of choices?

I've tried a few component libraries over the years but I found it hard to settle on one. Last year, I found out about Radix UI primitives. I instantly liked it. They are unstyled, have built-in accessibility and keyboard navigation, and have a nice API. And they can be styled with whatever technology we want. I'm a huge fan of Tailwind, so naturally, I chose that. Pretty soon, I had a collection of styled components that I could use for my prototypes, and I included them in my starter.

But I ran into a problem. Changing these components meant that the components began to diverge across my projects and copy-pasting got tired very fast. So I decided to bite the bullet and build a component library. CatalystUI is the result of this work.

Another, and probably the most exciting reason I wanted to build a component library is to learn how to build a good one. Because component libraries and by extension design systems are hard. Providing a good abstraction on top of the existing unstyled components is hard. And what better way to learn than by doing it?

What's on the roadmap?

In its current state, Catalyst doesn't have all the Radix primitives. There are a basic set of components with an API that I think works for me. Using them will reveal any potential problems. The same goes for the built-in styles and extending those styles in my projects. So first on my list is making the API and styles consistent across the components.

Radix has a good set of primitives. They're atomic — they do one thing and do that well. Catalyst has to first cover all of the available primitives. In addition to that, I want to build more complex components that can be just dropped into an app and will work. Components like navbar, pagination, etc save a ton of time but are not provided by Radix.

If you're interested in checking it out, here's the GitHub repo:

Share this on:Twitter