I’ve been “fighting” against Tailwind for a while, and there’s 4 different kinds of reactions:
- Please stfu, Tailwind is awesome, [insert technical argument]
- Johan, why do you bore me with these technical things? Can you please tweet about cooking? And where is your new post about sim racing?
- If you don’t like it, just don’t use it
- Nod – you are right (this is mostly coming from the people from my same “generation” who learned web development around the same time as I did)
Yesterday someone reached our privately, basically to challenge me to channel this negative energy into something positive. I agree that would be nice.
For now you will have to do with this blog post which is still in the rant-o-sphere. But I will take up the challenge to maybe work on something that shows my opinion on how to do it “right”. That’s going to take some time though.
Why do I get so worked up about Tailwind? Because bad frameworks create problems that shouldn’t exist.
I help to maintain Routify, at least from a community and docs perspective. Quite a few support questions that come in are about dev pipelines, and some of them about Tailwind. A CSS framework I don’t like creates a support problem for me. I cannot simply ignore it (so that’s a rebuttal against the point to simply ignore the existence of Tailwind).
What I see is that bad frameworks create a crazy learning path for new devs, where they might waste months learning to work with frameworks with crazy APIs only to find out that they haven’t really learned anything.
Learning modern web development is already intense. But at this point in time, a lot of modern web development leads you down a path where you might not learn all that much, because you are fighting poor decisions made by other people. Maybe if you’re new to this, you think that’s just the way things have to be.
One thing that I want to mention is that not everything about Tailwind is bad. I think the visual look is quite solid. The way the framework is promoted is well done, with well-produced video content and blogging that has gone professional. I mean, this team knows their stuff. I just fundamentally disagree with the premise of littering your HTML with classes. I disagree with shipping a framework that has accessibility issues.
I am often in a position where I am mentoring new hires to our company. A few months ago I pointed someone new to Adam Wathan’s article “CSS Utility Classes and “Separation of Concerns””. This is a great article by the author of Tailwind.
I guess with the above I just want to point out that I am not blind to the Good Parts of Tailwind (just like there are good parts to React ;) *shields from incoming flames*)
But overall I am worried that some framework makers live in their own theoretical world and forget about the real world. They are striving for a technically perfect framework but forego the real-life usage. For them the framework is the project and the lens they view things through. The usage and the actual project where their framework is used is just a detail. When it should be the other way around.
This kind of perspective leads to frameworks that constantly change their mind about what they want to be, leading to work down the line for the users, that often has no real-life value at all.
In my blog posts taking down Tailwind I am mainly writing from a worry of having to maintain a codebase full of classes.
Somebody tweeted this screenshot and I’m like: seriously?
If you look really well you can see that this shows a heading and 2 buttons, but it’s a bit hard to see. If you’re interested why this is just a poor way to develop your things you can go back to the blog posts and see what I had to say.
Today this post is more about a broader perspective. I eventually gave this post the title “Hey, your API surface is causing unnecessary complexity”. This was triggered by Tailwind basically repackaging CSS gradients in their own proprietary syntax and then limiting what you can do with gradient because they don’t support everything. And I’m like: why not simply use CSS? Like, which problem does this solve?
It just adds to the complexity of Tailwind. It creates something new for a dev to understand when they find this code. It creates a new documentation page that has to be maintained. It creates a new surface area for bugs. I think sometimes you just have to stop developing a framework. Sometimes, things are finished. The problem with Tailwind is that since it basically mirrors CSS, it will simply never be finished as long as CSS keeps adding new features. Which they should also put a stop to, in my opinion.
I see what I’m talking about – adding unncessary complexity — happening with both SCSS and the CSS working group. In October last year, SCSS modules were announced and literally nobody cared. I love SCSS – I have been working with Sass since the early days and contributed to the first documentation site of Compass. That was my first introduction to open source. But Sass/SCSS has now reached a maturity point that what people are adding is so niche that nobody really cares anymore. Look: SCSS was already done.
Now the CSS working group is discussing some sort of cascade layering system within CSS itself.
I applaud the efforts to try and solve problems with CSS, but I also fear that maybe they are in vain. I think CSS is already complex enough. You can read my thoughts in the comment below the linked spec.
In a discussion with a fellow dev about Svelte 3, he said Svelte 3’s API is nearly perfect. There is not much to add. In a lot of the pull requests about Svelte where people try to add features, there is pushback because it will make the framework more complex. Personally I love this. I want people to be able to attain Svelte mastery. To understand the API in full.
I don’t want a framework that has a thousand nooks and crannies and that has 2 or 3 ways to do things.
In React world there is the pre-hooks way and the post-hooks way. In Ember world there is non-Octane and Octane. Vue is moving to Vue 3, but at least that is backwards-compatible.
Maybe Svelte will go to a transition at some point where there is a Svelte (4?) API that is vastly different; maybe it won’t.
But I think people should realize they can’t keep adding complexity on top of complexity. People should really stop and think if you really need 500+ Mb worth of
node_modules to build a simple website. Developers need to think about the API surface of the tools they are building. There is an optimum point where it’s better to stop instead of cramming in feature after feature.
We are moving towards a world where people are doing web development where they are purging a 1.4Mb CSS file to 28kb ( for the actual selectors they used) on a CI environment that they don’t control. And then one day AWS goes down, and maybe npm gets hacked, and the poor web dev who hasn’t built up fundamental skills doesn’t really know how to do anything anymore, because they always depended on others (what is SSH anyway?).
I think people need to know fundamentals. You can’t depend on a few magical incantations on the terminal that you don’t fully understand.
The same goes for any kind of development. When you write a CSS rule you have to understand what it does and where it is coming from.
When you deploy a website you have to understand what is happening behind the scenes.
When you use a framework, you have to work towards understanding it in full. You have to know why it exists and why you use it.
If somebody wants to use Tailwind and has a set of reasons, that’s fine for me. What I don’t like is people defaulting to things that are popular and then learning a stack that basically abstracts the fundamentals; this leads to a situation where junior web devs work for 3 years but lack fundamental skills because they were too busy trying to fix local problems created by poor frameworks. And that’s what I’m fighting.