Anjolaoluwa Adebayo-Oyetoro Maker. Writes sometimes. Playful most times. Loves beautiful UIs.

How to use Tailwind CSS in React to configure Create React App

5 min read 1602

tailwind css and cra

Editor’s note: This Tailwind CSS and React tutorial was last updated on 19 February 2021 to reflect changes introduced with the latest Tailwind CSS release, Tailwind CSS v2.0. The instructions and configurations described herein have been updated accordingly.

Recently, I tried using Tailwind CSS in a React project bootstrapped by the Create React App (CRA) boilerplate and ran into difficulties setting up Tailwind CSS as CRA abstracts configuration.

To make custom configurations, you would have to eject Create React App to have full access to tinker with the configurations, which also means a much more tedious setup — and should anything break, you’re on your own. I tinkered a bit, and after several Google searches, I found a better way to get it done.

In this tutorial, we’ll demonstrate how to to make Tailwind CSS work inside your React project without having to eject Create React App.

To follow along with this tutorial, you should have

Using Tailwind CSS in your React boilerplate project

First, open your terminal and type the following commands to create a new project.

#using NPX
npx create-react-app tailwindreact-app

#using NPM
npm init react-app tailwindreact-app

#using yarn 
yarn create react-app tailwindreact-app

create-react-app is the official React build tool for scaffolding new React projects. It leverages webpack and babel and reduces the hassle of configuring and setting up the build processes for projects, allowing you to focus on writing the code that powers your app.

Add cd to your app directory:

cd tailwindreact-app

Next, install Tailwind and its dependencies:

#using npm
npm install -D [email protected]:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat [email protected]^7 [email protected]^9

#using Yarn
yarn add [email protected]:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat [email protected]^7 [email protected]^9 -D 

Create React App does not support PostCSS 8 yet, so we’ll install the version of PostCSS 7 that is compatible with Tailwind CSS v2.

As stated in the PostCSS documentation:

PostCSS is a tool for transforming styles with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.

Autoprefixer is a PostCSS plugin that parses your CSS and adds/removes unnecessary vendor prefixes in your compiled CSS rules. It can help you add prefixes for animations, transition, transform, grid, flex, flexbox, etc.

How to configure CRACO

Since Create React App doesn’t let you override the PostCSS configuration by default, we’ll need to install CRACO to configure Tailwind.

#using npm
npm install @craco/craco

#using Yarn
yarn add @craco/craco

CRACO, short for Create React App configuration override, is an easy and comprehensible configuration layer for Create React App. It provides all the benefits of create-react-app and customization and eliminates the need to “eject” your app by adding a craco.config.js file at the root of your application to customize with your eslint, babel and PostCSS configurations.

First, create a CRACO configuration file in your base directory, either manually or using the following command:

touch craco.config.js

Next, add tailwindcss and autoprefixer as PostCSS plugins to your CRACO config file:

// craco.config.js
module.exports = {
  style: {
    postcss: {
      plugins: [
        require('tailwindcss'),
        require('autoprefixer'),
      ],
    },
  },
}

Configure your app to use craco to run development and build scripts.

Open your package.json file and replace the content of "scripts" with:

  "start": "craco start",
  "build": "craco build",
  "test": "craco test",
  "eject": "react-scripts eject"

Your scripts file should look like this:

  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
}

Create the default configurations scaffold:

npx tailwindcss init

This command creates a tailwind.config.js in your project’s base directory. The file houses all of Tailwind’s default configuration. We can also add an optional --full flag to generate a configuration file with all the defaults Tailwind comes with.

You’ll get a file that matches the default configuration file Tailwind uses internally.

Including Tailwind in your CSS

Inside your src folder create a folder named styles. This is where all your styles will be stored.

Inside that folder, create a tailwind.css and an index.css file.

The index.css file is where we’ll import tailwind’s base styles and configurations. tailwind.css will contain the compiled output of the index.css.



Tailwind CSS components, utilities, and base styles

add the following to your index.css file.

//index.css
@tailwind base;

@tailwind components;

@tailwind utilities;

@tailwind is a tailwind directive that is used to inject default base styles, components, utilities and custom configurations.

@tailwind base **injects Tailwind’s base styles, which is a combination of Normalize.css and some additional base styles.

@tailwind components injects any component (small reusable styles such as buttons, form elements, etc.) classes registered by plugins defined in your tailwind config file.

Below the component import is where you would add any of your custom component classes — things that you’d want to be loaded before the default utilities so the utilities could still override them.

Here’s an example:

.btn { ... }
.form-input { ... }

@tailwind utilities injects all of Tailwind’s utility classes (including the default and your utilities), which are generated based on your config file.

Below the utilities import is where you would add any custom utilities you need that don’t come out of the box with Tailwind.

Example:

.bg-pattern-graph-paper { ... }

.skew-45 { ... }

Tailwind swaps all these directives out at build time and replaces them with the CSS generated.

Configure your app to build your CSS file

To configure your app to use CRACO to build your styles every time you run the npm start or yarn start command, open your package.json file and replace the content of "scripts" with:

  "scripts": {
    "build:style": "tailwind build src/styles/index.css -o src/styles/tailwind.css",
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },

To import your CSS to the app, open your index.js file and import your Tailwind styles:

import './styles/tailwind.css';

Delete the index.css and app.css files in your projects root directory and remove their corresponding import statements in the Index.js and App.js files, respectively.

Your index.js file should look similar to this:

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';

After deletion, it should become:

//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './styles/tailwind.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

Your App.js file should look like this before deletion:

//App.js
import logo from './logo.svg';
import './App.css';

After deletion, it should become:

//App.js
import logo from './logo.svg';

These changes would cause an output similar to this:

browser output
Output in your browser after deleting your index.css and app.css

Testing your Tailwind CSS configurations

To test that our configurations work correctly, let’s create a simple sign-in form.

Open your App.js file and replace the content between the return function with the following:

    <section className="App h-screen w-full flex justify-center items-center bg-green-500">
      <div className="w-full max-w-md bg-gray-800" >
        <form action="" className=" bg-white shadow-md rounded px-8 py-8 pt-8">
          <div className="px-4 pb-4">
            <label htmlFor="email" className="text-sm block font-bold  pb-2">EMAIL ADDRESS</label>
            <input type="email" name="email" id="" className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline border-blue-300 " placeholder="[email protected]" />
          </div>
          <div className="px-4 pb-4">
            <label htmlFor="password" className="text-sm block font-bold pb-2">PASSWORD</label>
            <input type="password" name="email" id="" className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline border-blue-300" placeholder="Enter your password" />
          </div>
          <div>
            <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" type="button">Sign In</button>
          </div>
        </form>
      </div>
    </section>

We gave the paren section width of 100% with w-full. We also gave it a vertical height of 100vh with h-screen. Then we gave the element a display property of flex and aligned it to the center vertically and horizontally with justify-center and items-center.

We gave the child div a width of 100% with w-full and set the max-width with max-w-md for medium screens and larger.

We gave the form a white background with bg-white and a border radius to achieve the curved borders with border. px-8 and py-8 add a padding of 8px to the x-axis and y-axis, respectively, while pt-8 adds a padding of 8px to the top of the form.

We added a font-size of .875rem to the label element with text-sm, gave the element a display of block, and set the font-weight to a value of 700 with font-bold.

On the input element, we gave the element some box shadow with shadow and used .appearance-none to reset any browser-specific styling on the input element.

We added a line-height of 1.25 with leading-tight and used the pseudo class focus to remove browser-specific outlining of the focused input element with focus:outline-none and added a bit of box shadow with focus:shadow-outline.

You should get a result similar to this:

input form

Check out an editable example on CodeSandbox.

Conclusion

In this post, we reviewed how to configure Create React App to use Tailwind CSS. Tailwind has awesome documentation. Check it out for more information. You can also access the code used in this tutorial on GitHub.

Get setup with LogRocket's modern React error tracking in minutes:

  1. Visit https://logrocket.com/signup/ to get an app ID.
  2. Install LogRocket via NPM or script tag. LogRocket.init() must be called client-side, not server-side.
  3. $ npm i --save logrocket 

    // Code:

    import LogRocket from 'logrocket';
    LogRocket.init('app/id');
    Add to your HTML:

    <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
    <script>window.LogRocket && window.LogRocket.init('app/id');</script>
  4. (Optional) Install plugins for deeper integrations with your stack:
    • Redux middleware
    • ngrx middleware
    • Vuex plugin
Get started now
Anjolaoluwa Adebayo-Oyetoro Maker. Writes sometimes. Playful most times. Loves beautiful UIs.

21 Replies to “How to use Tailwind CSS in React to configure…”

  1. Hey btw for this “`”scripts”: {
    “build:style”:”tailwind build src/styles/index.css -o src/styles/tailwind.css”,
    “start”: “npm run build:style && react-scripts start”,
    “build”: “react-scripts build”,
    “test”: “react-scripts test”,
    “eject”: “react-scripts eject”
    },“` You still have npm instead of using yarn.

  2. Hi!
    Thanks for the tutorial.
    One thing that might be nice to add is if you want to generate styles based on the taildwind config file, the build:style should be changed to:

    “build:style”: “tailwind build src/styles/index.css -c tailwind.js -o src/styles/tailwind.css”,

  3. Hi Dennis,
    I don’t find any difference in using “tailwind build src/styles/index.css -o src/styles/tailwind.css” instead of what you have above said. Is there any hidden difference could you explain?

  4. Thanks for the tip! This helped a lot.

    I was scratching my head because `tailwindcss(‘./tailwind.js’)` in `postcss.config.js` looked like it should work. But that doesn’t work. Maybe they updated the API?

    The file should look like this:
    “`
    // postcss.config.js

    module.exports = {
    plugins: [require(“tailwindcss”), require(“autoprefixer”)]
    };
    “`

    Also, making `@import` didn’t get me anywhere. I thought maybe I should go that route, but if you’re having trouble getting the tutorial to work I’d updated the build style and update `postcss.config.js` to what I have above first.

  5. Sorry if I’m wrong, isn’t the script “build:style” should be using “postcss” instead of “tailwind”?

  6. You have to add it to your tailwind config. If you want to do the styling for a background add it like below. Not the extra key ‘group’ added to the variants.

    module.exports = {
    // …
    variants: {
    backgroundColor: [‘responsive’, ‘hover’, ‘focus’, ‘group’],
    },
    }

  7. Followed all the steps, then yarn start.
    and I am stuck with this in terminal:

    $ yarn start
    yarn run v1.19.2
    $ npm run watch:css && react-scripts start

    > [email protected] watch:css D:\React\ecommerce\crm\crm
    > postcss src/styles/tailwind.css -o src/styles/app.css -w

    //My app.css has been populated but the app is not starting.
    //Compiled succesfully message is not showing.

  8. Will this work after eject? How do you load the new UI components? …
    Just asking. I honestly got no idea – which is why I prefer things being implemented in a more controlled way.

  9. I think you don’t have to eject the script instead use react-app-rewired more info available here https://github.com/timarney/react-app-rewired

    I have configured tailwind using react-app-rewired

    this is my configuration :

    const tailwindcss = require(‘tailwindcss’);
    module.exports = config => {
    require(‘react-app-rewire-postcss’)(config, {
    plugins: loader => [
    tailwindcss(‘./tailwind.js’),
    require(‘autoprefixer’)
    ]
    });
    return config;
    };

  10. This way your css won’t update when you run it with npm start as it is compiled only once.
    Use npm-run-all (npm install –save-dev npm-run-all) and change your scripts in package.json to run both css watcher and react project paralell (the “run-p” means run paralell).
    “build:tailwind”: “postcss src/tailwind.css -o src/tailwind.generated.css”,
    “watch:tailwind”: “postcss -w src/tailwind.css -o src/tailwind.generated.css”,

    “start”: “run-p watch:tailwind start:react”,
    “start:react”: “react-scripts start”,

  11. Thanks OP! Wonderful article. The code snippet in the end, `sectiom` has a typo. Should be `section`.
    Also, since @tailwind base; @tailwind components; @tailwind utilities; are being imported on the index.css file, index.js must import index.css instead of tailwind.css for the example to work. Thank you!

  12. If ever I needed something to remind me how ludicrously complex React/frond-end development has become this has to be it. So many fragile pieces tied together with duct tape. I need to get back to being productive with Rails or Golang or something. Even Java is better than this.

Leave a Reply