In Defense of Tailwind: Why Utility-First Still Works
Colton Dev recently published a post titled “Tailwind is the worst of all worlds”, and I get where he’s coming from. Tailwind isn’t for everyone. But after building multiple projects with it — from simple CMS frontends to full-featured web apps — I think it deserves a more balanced perspective.
Let’s break down the common criticisms and why I still think Tailwind is a solid tool.
1. “Tailwind makes HTML unreadable”
Sure, at first glance, Tailwind classes look like a chaotic pile of utility soup:
<div class="text-sm font-medium text-gray-700 hover:text-blue-500">
But once you’ve spent time with it, that string becomes intuitive. Yes, you can end up with long class lists, but Tailwind gives you ways to manage that:
- Break out components (Blade, Vue, React…)
- Use logical grouping (multiple lines, sorted classes)
- Use
@apply
— sparingly — for things like buttons or badges
And to be clear: Tailwind still supports @apply
, but the core team advises against overusing it. It’s not there to “rebuild Bootstrap,” but it’s great for abstracting the right bits.
2. “There’s no separation of concerns”
This one’s more philosophical than practical. Tailwind trades traditional separation (HTML in one file, CSS in another) for co-location: the styles live next to the markup they affect.
That might sound wrong to some ears, but in component-driven development, it’s often a win. Instead of chasing down class names across files, you see everything you need in one place. It’s a different kind of clarity.
3. “Tailwind makes design systems harder”
If you don’t use Tailwind’s config properly, sure. But the config is the design system. You define spacing, colors, fonts, shadows — and those become your constraints.
You can:
- Lock arbitrary values
- Define semantic naming (
primary
,danger
,muted
) - Extend tokens with consistency baked in
Like anything, you get out what you put in. Tailwind doesn’t enforce design discipline — but it doesn’t prevent it either.
4. “Just write CSS”
You can. No one’s stopping you. But Tailwind’s value isn’t that it eliminates CSS — it’s that it reduces the friction around it.
You don’t name things. You don’t think about selector specificity. You don’t worry about global scope. You just reach for the tools and keep moving on.
I’ve used BEM, SCSS, styled-components, CSS Modules. They all have merits. But for many everyday UI tasks, once you get used to it Tailwind is the fastest, clearest, most low-maintenance option I’ve worked with.
5. “It’s just a wall of class names”
Honestly, I think this one turns people off visually, more than functionally. We’re used to seeing neat class names like .card
, .hero
, or .button--primary
. Tailwind trades that for bg-white shadow-md rounded-lg p-4
.
It’s noisier. It’s less pretty. But you stop noticing.
What you gain is direct control — no indirection, no guessing what .card--light
actually does. The class is the style.
And once you start working on components, those “walls of class names” get smaller and more scoped.
Final thoughts
Tailwind isn’t perfect. It’s not traditionally elegant — but it’s fast, flexible, and, with a little structure, surprisingly clean.
If you’re building UIs solo, you’re thinking about clarity. You want styles that are predictable, components that are consistent, and tools that don’t get in your way. You’re not trying to over-engineer — you just want a system that lets you stay focused on the interface and how it feels.
Tailwind doesn’t demand a design system up front. It helps you grow one as you build — piece by piece — without sacrificing control along the way.
And in larger projects, where naming conventions tend to drift, utility-first CSS sidesteps a common problem: developers creating slightly different class names (.card-primary, .primary-card, .card--highlighted
) just to avoid breaking something they don’t fully understand. With Tailwind, there’s no fear of hidden globals — the class is the style.
And if utility-first isn’t your thing? That’s okay too. But let’s not throw out the baby with the bathwater.