Using a meal kit is a seductive trap. You get the pre-chopped carrots and the pre-measured sauce, and suddenly you’re a chef because you followed three steps to assemble a dish. It feels like a win because you didn’t have to spend an hour prepping or learn how to actually balance flavors from scratch. But you haven’t actually learned how to cook; you’ve just learned how to follow a set of instructions provided by a company that wants to make sure you keep paying for the subscription.
The “productivity” argument for Tailwind is the same one used to sell those meal kits. We are told that naming classes is a waste of time and that slapping flex items-center justify-between directly onto a div is the height of efficiency. (Probably because we’ve all been lied to by a “productivity” tool before). But naming things is one of the two hardest problems in computer science for a reason. When you name a class .user-profile-header, you are describing what the element is and its role in the application. When you use Tailwind, you are describing what the element looks like in a specific instance. This is a fundamental regression in how we think about the web. We’ve traded semantic architecture for a list of visual attributes, effectively turning our HTML into a giant, fragmented style sheet.
Since when did we decide that the HTML file should also be the style sheet? If you look at the argument in why-i-dont-recommend-tailwind-css, the core issue is the cognitive load of reading a wall of text that looks like a cat walked across a keyboard. It is one thing to write these classes when you’re in the flow of a new feature; it’s another thing entirely to maintain a project where every single element has thirty attributes. It’s like reading a novel where every adjective is replaced by a technical specification of the object’s color and size. You might eventually get the picture, but the prose is ruined, and the intent of the author is buried under a mountain of minutiae.
Then there is the friction of the toolchain. To get Tailwind working, you aren’t just writing CSS; you’re managing a PostCSS pipeline, a configuration file, and a build step that has to purge unused classes so your production CSS isn’t five megabytes. For a language that was designed to be interpreted by a browser without a single line of compilation, we’ve added a massive amount of overhead just to avoid writing a few .css files. It’s a strange trade-off: we avoid the “difficulty” of the cascade by introducing the complexity of a build system. We’ve basically built a compiler to avoid writing a language that doesn’t need one. Or maybe I’m just old—no, the math still doesn’t add up.
The industry is currently in a Tailwind fever dream, but the pendulum always swings back. We’ve seen this before with the rise and fall of various “CSS-in-JS” libraries that promised to solve the same problems and ended up creating new ones. As native CSS nesting and CSS variables become the standard across all modern browsers, the need for a utility-first framework disappears. By Q4, we will see a significant migration back toward native CSS modules and vanilla stylesheets in the top ten most popular frontend boilerplates. The “convenience” of Tailwind is a short-term gain that leads to long-term technical debt and unreadable code. We are trading the long-term health of our codebases for the immediate gratification of not having to think about a class name.
Tailwind is just inline styling with a better marketing budget.