Obinna Ekwuno Writer of all things Technical and inspirational , Developer & Community Advocate. In a love-love relationship with JavaScript🔥.

Tailwind CSS: Is it tomorrow’s Bootstrap?

6 min read 1847

We’re experiencing a renaissance of amazing web platforms and responsive design. Responsive user interfaces have mostly been implemented with libraries like Bootstrap, Foundation, Bulma, or good old-fashioned media queries.

We have used these UI kits with ease to implement directives to achieve the exact UI and proper responsiveness we require with less code. But the big question is, have we really been doing it right?

What if there was a way to achieve responsive UI without being bound by the rules of any UI kit? Is there a way to achieve responsiveness and still keep our custom user interface designs? Well, let’s find out.

What is Tailwind CSS?

According to the official documentation, Tailwind CSS is a utility-first CSS framework for rapidly building custom user interfaces. I like to think of it as a cool way to write inline styling and achieve an awesome interface without writing a single line of your own CSS.

In my opinion, the one thing that most developers will find a bit distracting with Tailwind CSS is the fact that your markup looks a lot busier than you might like. Tailwind isn’t the first utility CSS library, but it is the most popular at the moment.

Getting started

Although CDN is a good way to import styling in your project, many features of Tailwind CSS are not available using the CDN builds. To take full advantage of Tailwind’s features, install Tailwind via npm.

1. Install Tailwind via npm

Tailwind is available on npm and can be installed using npm or Yarn.

# Using npm
npm install tailwindcss --save-dev
# Using Yarn
yarn add tailwindcss --dev

2. Create a Tailwind config file

Tailwind is configured almost entirely in plain JavaScript. To do this, you’ll need to generate a Tailwind config file for your project. It is recommended to create a tailwind.js file in your project’s root. The CLI utility helps handle this easily.

# Using npm
npx tailwind init [filename]
# Using Yarn
yarn tailwind init [filename]

If you’re an experienced Tailwind user who doesn’t need the comments in the config file, you can use the --no-comments flag when generating your config file to strip them out. For more info on setting up, check out the official documentation.

The problem with UI kits

First of all, let’s look at what we have been doing and how we can do a better job of adding flexibility to the framework. Then, let’s explore why using UI kits probably aren’t the best choice in light of newer information.

We made a custom demo for .
No really. Click here to check it out.

Frameworks like Bootstrap have abstracted the creation of components to the point where it compels developers to use only the available patterns provided. The same goes for other UI kit-type frameworks.

Some might argue that overriding the framework with our own CSS is an option, but if we override a lot, then is there really any point in using the framework? We’d be pulling in the library and still writing our own code — this is just more files to worry about, and we are not even saving time.

Another problem I have found with Bootstrap sites is that they almost always look alike, so this inhibits our ability to incorporate creativity into the dev environment. This is one of the advantages of Tailwind CSS: its ability to easily build complex user interfaces without encouraging any two sites to look the same.

What does “utility-first” even mean?

A utility-first library simply means that unlike Bootstrap, Tailwind doesn’t give us automatically prestyled components. Rather, it gives us utility classes that help us style our component in certain ways and allows us to build our own classes using these utility classes. Let’s explain this further using two simple examples.

Example 1: Simple button demo

See the Pen
Box example .
by Ekwuno Obinna (@ekwunoobinna)
on CodePen.

From the above example, we can see how easy it is to implement a button component with Tailwind CSS.

Example 2: Simple card demo

The code below is a simple example of a card created with the Tailwind CSS framework — and if you are familiar with CSS, you might already be able to make out some of the things going on with the styling. It might be a bit tricky memorizing all of this at first, but once you have some familiarity with the syntax, you will be alright.

The code snippet below has a container that has a shadow for large screens due to the shadow-lg class and a background of white implemented by using bg-white. We can also notice the px-4 and py-1 classes are just to help with padding in the x- and y-axes for the message button.

<div class="bg-white mx-auto max-w-sm shadow-lg rounded-lg overflow-hidden">
  <div class="sm:flex sm:items-center px-6 py-4">
    <img class="block h-16 sm:h-24 rounded-full mx-auto mb-4 sm:mb-0 sm:mr-4 sm:ml-0" src="" alt="">
    <div class="text-center sm:text-left sm:flex-grow">
      <div class="mb-4">
        <p class="text-xl leading-tight">Adam Wathan</p>
        <p class="text-sm leading-tight text-grey-dark">Developer at NothingWorks Inc.</p>
        <button class="text-xs font-semibold rounded-full px-4 py-1 leading-normal bg-white border border-purple text-purple hover:bg-purple hover:text-white">Message</button>

Here is a CodePen that shows what the above code looks like:

See the Pen
Tailwind Css Card
by Ekwuno Obinna (@ekwunoobinna)
on CodePen.

Is there a performance advantage to using Tailwind CSS?

The default Tailwind configuration comes with 36.4kb minified and g-zipped. Compare this to Bootstrap at 22.1kb — Tailwind is 14.3kb heavier. You might be thinking,”Is this really the way to go in terms of performance?”

The reason for this is simple: Tailwind comes prepacked with a lot of options and styles for users to choose from, and it packs all these variations to reduce the tendency to write your own CSS. Fortunately, Tailwind comes with a few strategies you can use to keep your generated CSS small and performant.

Limit your color palette

Due to the fact that all the built-in utility modules in Tailwind use the plugin system under the hood, it’s possible to delete a ton of code and make the plugin system the way that new classes are registered inside Tailwind.

This makes it possible to have only code we actually need in projects while ignoring everything else — unlike Bootstrap, in which there is a lot of overhead code. This upgrade feature shortens the build time from 158s to 8s.

We can get the exact amount of color variations we need in a project, like so:

// ...

module.exports = {
  // ...

  textColors: {
    'black': colors['black'],
    'grey-darker': colors['grey-darker'],
    'grey-dark': colors['grey-dark'],
    'red-dark': colors['red-dark'],
    'red': colors['red'],
    'blue-dark': colors['blue-dark'],
    'blue': colors['blue'],
    // ...

Remove unused CSS with PurgeCSS

Tailwind also removes unused CSS with PurgeCSS, a tool for removing unused CSS from your project. It does this by simply comparing the CSS class names available in your template against the class names used and then removing the unused CSS.

Pick the exact number of screens you need

Tailwind allows you to pick the exact amount of screen sizes you need. Here’s how defining fewer screens affects the output:

  • 5 screen sizes (default): 36.4kb
  • 4 screen sizes: 29.4kb
  • 3 screen sizes: 22.4kb
  • 2 screen sizes: 15.4kb
  • 1 screen size: 8.4kb

So exactly how flexible is Tailwind CSS?

Are you ready for this? Are you sure? OK, so Tailwind is so flexible it allows you to add your own utilities and provides a guide for you to implement this.

Let’s take a simple style implementation as an example. A normal Tailwind setup is a single CSS file that looks like this:

@tailwind preflight;

@tailwind components;

@tailwind utilities;

So to override the default utilities, we would have to import the override last so that it’s applied first (common CSS rule):

@tailwind preflight;

@tailwind components;

@tailwind utilities;

.bg-cover-image {
  background-image: url('/path/to/image.jpg');

But if you are using postcss-import or a preprocessor like Less, Sass, or Stylus, keeping your utilities in a separate file and importing them would be the best move:

@tailwind preflight;

@tailwind components;

@tailwind utilities;

@import "leveledup-utilities";

Note: The same can be done for responsive layouts. Custom utilities will always take precedence over prefixed utilities as long as it is done properly.

Extracting utility patterns with @apply

So, let’s say you were reusing a certain button style in several places. Retyping the same type of specification for the same component becomes a bit boring. Not to worry: Tailwind has a way to reuse styling with @apply.

Here is an example:

<button class="btn-gray">

.btn-blue {
  @apply bg-gray text-white font-bold py-2 px-4 rounded;
.btn-gray:hover {
  @apply bg-gray-dark;

Note: hover:, focus:, and {screen}: utility variants can’t be mixed in directly.

Is Tailwind production-ready?

Tailwind CSS just released version 1.0.0.beta, and the following features are production-ready:

Expanding default color palette

This new version of Tailwind comes with some upgrades to aid flexibility in using color shades by replacing the original seven-shade, darkest-to-lightest color system with a new nine-shade numeric color system, where 100 is the lightest shade and 900 is the darkest shade.

Using progressive maxWidth scale

While we already had a linear scale for maxWidth (10rem), this new upgrade switches to a progressive scale where the value of the width increases and now has more default options from 9 to 12.

This default maxWidth scale can be overwritten by specifying the values you want for your own project in your config file:

module.exports = { 
  theme: { 
      maxWidth: { 
      // Your values go here... 

And lots more — it also comes more stable and ready for production.

Is this really the future?

Working with Tailwind CSS is using a set of utility classes that lets you work with exactly what you need. In my opinion, this is a neat way to create user interfaces that are more flexible to developers’ creativity.

Another advantage I really appreciate — and I am sure every front-end developer would also appreciate — is never having to worry about changes to one element affecting another related element. No more tabbing back and forth between HTML and style sheets in your editor, no more going back to check and see what you named that other element. In my opinion, this is the future.

Check out the official documentation and get started with this awesomeness. Happy coding!

You come here a lot! We hope you enjoy the LogRocket blog. Could you fill out a survey about what you want us to write about?

    Which of these topics are you most interested in?
    ReactVueAngularNew frameworks
    Do you spend a lot of time reproducing errors in your apps?
    Which, if any, do you think would help you reproduce errors more effectively?
    A solution to see exactly what a user did to trigger an errorProactive monitoring which automatically surfaces issuesHaving a support team triage issues more efficiently
    Thanks! Interested to hear how LogRocket can improve your bug fixing processes? Leave your email:

    Is your frontend hogging your users' CPU?

    As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.

    LogRocket is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

    Modernize how you debug web apps — .

    Obinna Ekwuno Writer of all things Technical and inspirational , Developer & Community Advocate. In a love-love relationship with JavaScript🔥.

    5 Replies to “Tailwind CSS: Is it tomorrow’s Bootstrap?”

    1. Need to update your code in the first example. `bg-purple` and `bg-purple-dark` no longer exist. Try `bg-purple-600 hover:bg-purple-800`

    2. “Another advantage I really appreciate — and I am sure every front-end developer would also appreciate — is never having to worry about changes to one element affecting another related element.”

      So if I change a component I need to change all other components manually to keep my layout consistent? That sounds really cumbersome and I don’t see how this is an improvement.

    3. Hey Bas!
      You have two basic choices for repeated elements here:
      1. use @apply in your CSS and build up your own class es for repeated components
      2. use Vue-, React- or PHP-Components and just include them whereever needed.
      It’s not too bad, for elements that lie beyond direct control, like WordPress’ WYSIWYG-Fields I just wrap that in a content class and use apply to style elements in there.


    4. Also for Bas,

      It can also depend on where you want to put your eggs.

      Do you want components you can guarantee won’t be effected or broken over time with a maximum css file size.

      Or do you want to update a handful of classes in the off chance your design requirement might change half way through. Which even if it does change, you get the benefit of not breaking other components by changing your design requirements 🙂

      People often forget that other programming languages apply the styling directly to the elements rather than global style sheets, so if it works for them! Can work for you

    Leave a Reply