I've worked with both for years at this point. Imo they each have their sweet spot depending on what kind of page you are building.
Bootstrap is a huge time-saver when you are mostly fine with the defaults it ships. Extending it means writing a CSS file, which brings up the ancient problem of "gosh dang what's again all the places where this class/subselector is used?". Even changing colors is usually a trial and error effort, because different components use different variables as their basis. If you ever were to change font sizes, you will quickly notice that paddings etc. also need adjustment, so it's not as trivial as one might assume.
Tailwind's pain & gain come from the other direction: It's super easy to have every element look the way you want, but you also have to specify it for every element, which means high chances of missing something resulting in inconsistent appearance. It's not enough that I can abstract out the <Button> component, because the font size and line spacing must be visually(!) consistent with the <Select>, so those two are semantically linked together, but tooling can't help me reliably with ensuring that. Tailwind is, in comparison to CSS also way more limited in what can be expressed. Take something like this as an example of what is not expressible in tailwind:
Fine I’ll chime in… The main advantage tailwind has is that utility css can be composed without needing to worry about hierarchy. This is not true for bootstrap.
This makes tailwind much more predictable for component based UI architecture, in your example you would define a <Button> component so that verbosity of css is explicitly defined once where it’s used, not buried within a bootstrap framework somewhere.
If you’re not using a component based architecture, then tailwind is much more verbose, but still useful, as copying/pasting tailwind HTML is insanely easy and reliable. This is not true for bootstrap.
Bootstrap has it’s place, it’s good for cases where you’ I don’t care about the details of how it looks. But with component based architectures, tailwind is a much more flexible and better abstraction in my opinion.
Personally, I'm on team bootstrap. But, yes, it is subjective.
After working on several projects, I've come to realized that (atleast for me), ready-made UI kits/componenets are more important that the framework itself.
I wouldn’t put them in the same category. Bootstrap has a much stronger opinion about how you write and structure CSS, while Tailwind is a framework for building a style system and writing arbitrary CSS that conforms to it. In practice, Tailwind is actually much closer to writing vanilla CSS. It does come with a widely used default (and very good, IMO) style system, but you ultimately apply arbitrary CSS rules just like vanilla.
Tailwind is certainly divisive. It’s better suited to component-based frameworks than templates or plain HTML, so a person’s background likely contributes to how they perceive it. Personally, I’ve worked a lot with vanilla CSS, opinionated libraries like Bootstrap, and Tailwind, and opinionated libraries are the only one I have no desire to use again. I generally want Tailwind in component-based projects and vanilla CSS in template-based projects.
At the end of the day, pick what you like and use it. They all get the job done.
Your postscript explains why: using the same "btn-primary" as every other user of the framework hints that you're not building something with its own visual identity.
For the rest of us, we throw that "bg-sky-500 hover:bg-sky-600 active:bg-sky-700 text-white px-4 py-2 rounded-lg" (or whatever color and shape matches our brand) into a component with a variant=primary property and call it a day. What developers actually see on a day-to-day basis is <Button variant="primary" />.
> Your postscript explains why: using the same "btn-primary" as every other user of the framework hints that you're not building something with its own visual identity.
You know that bootstrap is trivial to customise right?
It turns out identifying primary and secondary buttons is a pretty standard thing in any kind of UI that has... buttons.
TailwindCSS is useful for applying styles to isolated components, in paper-shredder scenarios. Devs using it get to ignore the cascade, don't have to name things, and can use the predefined spacing and colors.
It is of course quite unmaintainable (good luck with updating the class soup for a bunch of components across a project).
I personally just ... cannot. CSS in 2026 is incredibly powerful and beautiful. Embracing the cascade allows for minimal CSS (see ITCSS methodology). Standardizing spacing and type with https://utopia.fyi is brilliant. Standardizing colors with custom props is trivial.
But, it seems that a lot of people are not paid to think about CSS. Tailwind embraces that. LLMs love it, because it reduces the complexity of pure CSS.
- If you just paste an outerHTML from the dev tools, AI coding agents can immediately figure out what it will look like; debug styles; etc.
I personally preferred PicoCSS for a long time. Pico was nice, but it injected a lot of CSS var noise into the dev tools and I started fighting with the breakpoints.
More recently, I've been just doing handcrafted CSS with a bit of OpenProps.
Same, it feels like Bootstrap but much, much more customizable. When I'm not using ShadCN that's what I reach for by default, it's been much nicer to work with, personally.
What fresh fucking hell is this? I can't say I've had the (mis)fortune of being forced to work with Tailwind (I've seen the name enough to know it's something vaguely "CSS framework"-adjacent though).
Seriously, though what kind of crack induced nightmare state was required for someone to think up such an abomination, implement it, and then make it public for the world to see?
Furthermore, who in their right mind saw that and said "yep this is fine"?
Once you learn how to read it, it's actually pretty clear.
This element has a small amount of x and y padding that is suitable for (for example) keeping text away from the edge of the container. The text is white. The corners of this are rounded.
The background is the default intensity 'sky' colour, which darkens slightly on hover and darkens further when it's active.
You can take this from 77 characters to 189 like this:
Tailwind simplifies consistency, and frankly is pretty readable. It's not like <button type="button" class="button">Button</button> is exactly the pinnacle of human clarity and simplicity in the first place.
Of course there are other ways to do it, but this faux outrage demonstrates not that this is some 'fresh fucking hell' or some 'crack induced nightmare', but rather that you simply don't get it.
I didn't say I can't read it. I asked who thought it was a good fucking idea. I guess you've answered that implicitly.
Embedding every style directly into the style attribute is also readable, and as a side benefit it doesn't need a build step just to make your styles actually work.
I can now see exactly why OP made this post. If a client told me they don't want to use something akin to bootstrap or any other sane css library, and that instead I will need to ensure that every element has every manner of css states expressed as a faux class, I wouldn't even stop to make a coffee before telling them how far they can jump.
This sounds perfect for front end “developers" who struggle even with css, and want any reason possible to pad out their billable/working hours doing nothing productive.
Oh what's that, you want to change the style of standard button everywhere in the codebase?
No of course we can't just update a single css file you silly goose.
I feel like half the bad problems in web development are because JavaScript developers saw that j2ee guys had ant and whatnot, and said "hey what if we started inventing reasons to have a build step"?
> button class="button"
The thing is, that is more readable for a sane code base. If I can glance and know it's using the correct standard button class, it means I don't need to memorise the fucking pixel sizes and states of button paddings.
I get it alright. It's a solution looking for a problem that doesn't exist, and instead found a crowd of "developers" looking for anything shiny to pad their resume and keep themselves looking busy.
Clearly you’ve made your mind up so I won’t push harder, except one point:
> Oh what's that, you want to change the style of standard button everywhere in the codebase?
Tailwind excels when you are using component based frameworks. This change should be at least as simple as updating main.css, except it’s in Button.tsx
Not a tailwind geek myself but I think how they justify is "better to have a little extra spaghetti in your html code than create a truck load of spaghetti in your app.css stylesheet."
The alternative to using tailwind here is to define the specific style elements for each one in the css stylesheets yourself with something like this:
.bg-sky-500 {
background-color: blue;
}
Tailwind proponents argue that they avoid this "stylesheet hell" by picking ready pre-defined tailwind classes like bg-sky-500, etc. Plus they also argue that this workflow will increase productivity by standardizing "style mindsets" of your dev team who all will think "blue" means "sky-500" (for example).
Maybe it has use cases in deep or professional design work but for most backend or full-stack devs, bootstrap is definitely better than meddling with this structure.
AI just generates all this. The true take is that this argument all together is obsolete, you shouldnt even be writing tailwind by hand anymore
I've worked with both for years at this point. Imo they each have their sweet spot depending on what kind of page you are building.
Bootstrap is a huge time-saver when you are mostly fine with the defaults it ships. Extending it means writing a CSS file, which brings up the ancient problem of "gosh dang what's again all the places where this class/subselector is used?". Even changing colors is usually a trial and error effort, because different components use different variables as their basis. If you ever were to change font sizes, you will quickly notice that paddings etc. also need adjustment, so it's not as trivial as one might assume.
Tailwind's pain & gain come from the other direction: It's super easy to have every element look the way you want, but you also have to specify it for every element, which means high chances of missing something resulting in inconsistent appearance. It's not enough that I can abstract out the <Button> component, because the font size and line spacing must be visually(!) consistent with the <Select>, so those two are semantically linked together, but tooling can't help me reliably with ensuring that. Tailwind is, in comparison to CSS also way more limited in what can be expressed. Take something like this as an example of what is not expressible in tailwind:
``` .component { .listitem { p { color: red; } } .listitem.special { p { color: blue; } } } ```
Fine I’ll chime in… The main advantage tailwind has is that utility css can be composed without needing to worry about hierarchy. This is not true for bootstrap.
This makes tailwind much more predictable for component based UI architecture, in your example you would define a <Button> component so that verbosity of css is explicitly defined once where it’s used, not buried within a bootstrap framework somewhere.
If you’re not using a component based architecture, then tailwind is much more verbose, but still useful, as copying/pasting tailwind HTML is insanely easy and reliable. This is not true for bootstrap.
Bootstrap has it’s place, it’s good for cases where you’ I don’t care about the details of how it looks. But with component based architectures, tailwind is a much more flexible and better abstraction in my opinion.
It seems like Tailwind only makes sense when dealing with components. For more traditional web dev, Bootstrap makes much more sense to me.
Personally, I'm on team bootstrap. But, yes, it is subjective.
After working on several projects, I've come to realized that (atleast for me), ready-made UI kits/componenets are more important that the framework itself.
I wouldn’t put them in the same category. Bootstrap has a much stronger opinion about how you write and structure CSS, while Tailwind is a framework for building a style system and writing arbitrary CSS that conforms to it. In practice, Tailwind is actually much closer to writing vanilla CSS. It does come with a widely used default (and very good, IMO) style system, but you ultimately apply arbitrary CSS rules just like vanilla.
Tailwind is certainly divisive. It’s better suited to component-based frameworks than templates or plain HTML, so a person’s background likely contributes to how they perceive it. Personally, I’ve worked a lot with vanilla CSS, opinionated libraries like Bootstrap, and Tailwind, and opinionated libraries are the only one I have no desire to use again. I generally want Tailwind in component-based projects and vanilla CSS in template-based projects.
At the end of the day, pick what you like and use it. They all get the job done.
Sure Bootstrap is better, for you.
Your postscript explains why: using the same "btn-primary" as every other user of the framework hints that you're not building something with its own visual identity.
For the rest of us, we throw that "bg-sky-500 hover:bg-sky-600 active:bg-sky-700 text-white px-4 py-2 rounded-lg" (or whatever color and shape matches our brand) into a component with a variant=primary property and call it a day. What developers actually see on a day-to-day basis is <Button variant="primary" />.
Cant you just customize the css of btn-primary?
> Your postscript explains why: using the same "btn-primary" as every other user of the framework hints that you're not building something with its own visual identity.
You know that bootstrap is trivial to customise right?
It turns out identifying primary and secondary buttons is a pretty standard thing in any kind of UI that has... buttons.
oof, that looks like absolute trash. i don't get why you want to use something less readable than css but to each their own i guess
TailwindCSS is useful for applying styles to isolated components, in paper-shredder scenarios. Devs using it get to ignore the cascade, don't have to name things, and can use the predefined spacing and colors.
It is of course quite unmaintainable (good luck with updating the class soup for a bunch of components across a project).
I personally just ... cannot. CSS in 2026 is incredibly powerful and beautiful. Embracing the cascade allows for minimal CSS (see ITCSS methodology). Standardizing spacing and type with https://utopia.fyi is brilliant. Standardizing colors with custom props is trivial.
But, it seems that a lot of people are not paid to think about CSS. Tailwind embraces that. LLMs love it, because it reduces the complexity of pure CSS.
Better is subjective, but I will say:
Bootstrap seems to create less CSS soup, but more HTML soup. And Tailwind vice versa.
For an admin panel or something back office, I agree that Bootstrap seems simpler.
But for something user facing and working with a designer? Tailwind is easier to customise.
One advantage I've noticed for Tailwind:
- If you just paste an outerHTML from the dev tools, AI coding agents can immediately figure out what it will look like; debug styles; etc.
I personally preferred PicoCSS for a long time. Pico was nice, but it injected a lot of CSS var noise into the dev tools and I started fighting with the breakpoints.
More recently, I've been just doing handcrafted CSS with a bit of OpenProps.
This gets argued every week. It doesn't matter as long as you like what you like.
I like daisyui.
Same, it feels like Bootstrap but much, much more customizable. When I'm not using ShadCN that's what I reach for by default, it's been much nicer to work with, personally.
Thats what tailwind component libraries like daisyui are for
> bg-sky-500 hover:bg-sky-600 active:bg-sky-700 text-white px-4 py-2 rounded-lg
What fresh fucking hell is this? I can't say I've had the (mis)fortune of being forced to work with Tailwind (I've seen the name enough to know it's something vaguely "CSS framework"-adjacent though).
Seriously, though what kind of crack induced nightmare state was required for someone to think up such an abomination, implement it, and then make it public for the world to see?
Furthermore, who in their right mind saw that and said "yep this is fine"?
Once you learn how to read it, it's actually pretty clear.
This element has a small amount of x and y padding that is suitable for (for example) keeping text away from the edge of the container. The text is white. The corners of this are rounded.
The background is the default intensity 'sky' colour, which darkens slightly on hover and darkens further when it's active.
You can take this from 77 characters to 189 like this:
Tailwind simplifies consistency, and frankly is pretty readable. It's not like <button type="button" class="button">Button</button> is exactly the pinnacle of human clarity and simplicity in the first place.Of course there are other ways to do it, but this faux outrage demonstrates not that this is some 'fresh fucking hell' or some 'crack induced nightmare', but rather that you simply don't get it.
Why would you want all that into the html, instrad of defining it in css?
I didn't say I can't read it. I asked who thought it was a good fucking idea. I guess you've answered that implicitly.
Embedding every style directly into the style attribute is also readable, and as a side benefit it doesn't need a build step just to make your styles actually work.
I can now see exactly why OP made this post. If a client told me they don't want to use something akin to bootstrap or any other sane css library, and that instead I will need to ensure that every element has every manner of css states expressed as a faux class, I wouldn't even stop to make a coffee before telling them how far they can jump.
This sounds perfect for front end “developers" who struggle even with css, and want any reason possible to pad out their billable/working hours doing nothing productive.
Oh what's that, you want to change the style of standard button everywhere in the codebase?
No of course we can't just update a single css file you silly goose.
I feel like half the bad problems in web development are because JavaScript developers saw that j2ee guys had ant and whatnot, and said "hey what if we started inventing reasons to have a build step"?
> button class="button"
The thing is, that is more readable for a sane code base. If I can glance and know it's using the correct standard button class, it means I don't need to memorise the fucking pixel sizes and states of button paddings.
I get it alright. It's a solution looking for a problem that doesn't exist, and instead found a crowd of "developers" looking for anything shiny to pad their resume and keep themselves looking busy.
Clearly you’ve made your mind up so I won’t push harder, except one point:
> Oh what's that, you want to change the style of standard button everywhere in the codebase?
Tailwind excels when you are using component based frameworks. This change should be at least as simple as updating main.css, except it’s in Button.tsx
Why am I not surprised this rube Goldberg style machine seems like a rational thing to people who write xml to generate JavaScript to generate html.
Not a tailwind geek myself but I think how they justify is "better to have a little extra spaghetti in your html code than create a truck load of spaghetti in your app.css stylesheet."
The alternative to using tailwind here is to define the specific style elements for each one in the css stylesheets yourself with something like this:
.bg-sky-500 { background-color: blue; }
Tailwind proponents argue that they avoid this "stylesheet hell" by picking ready pre-defined tailwind classes like bg-sky-500, etc. Plus they also argue that this workflow will increase productivity by standardizing "style mindsets" of your dev team who all will think "blue" means "sky-500" (for example).
Maybe it has use cases in deep or professional design work but for most backend or full-stack devs, bootstrap is definitely better than meddling with this structure.