I felt this way too until I started using Tailwind. I feel like Tailwind (and perhaps atomic css in general) is one of those "don't knock it till you try it" kind of things.
But, with that said, I do feel Tailwind relies on components (such as React, Angular, whatever) to be most effective. You'd ideally stick that purple class in a Heading component and maintain consistency that way.
Been through this process. Thing is, when you have a <Heading> component, you might as well simply write a css module for that component. Tailwind is great for "fast prototyping" and quickly styling a bunch of static HTML though. Wouldn't use it for a larger single page app.
I might be overreacting to past projects, but I've almost always found bespoke css gets out of control. Most projects tame it with well defined values for margin, padding, etc, and applying and enforcing those values means you sort of end up creating your own Tailwind. The "atomic" side of Tailwind is nice, but so is the consistency in values it provides.
If I was to take the css module approach today, I might still find myself using Tailwind and @apply inside the modules.
But, with that said, I do feel Tailwind relies on components (such as React, Angular, whatever) to be most effective. You'd ideally stick that purple class in a Heading component and maintain consistency that way.