Anjolaoluwa Adebayo-Oyetoro Maker. Writes sometimes. playful most times. loves beautiful UIs

How to configure create-react-app to use Tailwind CSS

4 min read 1346

tailwind css and cra

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, we would have to eject CRA 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 with it a bit and found a better way to get it done.

In this post, I will be showing an easy way to make Tailwind CSS work inside your React project without having to eject create-react-app.


Getting started

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

#Using NPM
$ npx create-react-app tailwindreact-app

#Using Yarn
$ yarn create react-app tailwindreact-app

This bootstraps a new React app with all the necessary configurations and build pipelines (webpack, Babel).

cd into your app directory.

cd tailwindreact-app

Next, install Tailwind:

# Using npm
npm install tailwindcss --save-dev

# Using Yarn
yarn add tailwindcss --dev

Create the default configurations scaffold

npx tailwind init tailwind.js --full

This command creates a tailwind.js in your project’s base directory, the file houses all of Tailwind’s default configuration.

Install Autoprefixer and PostCSS-CLI like this:

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

npm install postcss-cli autoprefixer --save-dev
yarn add postcss-cli autoprefixer --save-dev

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.

While Autoprefixer is a PostCSS plugin, it basically 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 PostCSS

Create a PostCSS configuration file in your base directory manually or using the command:

$ touch postcss.config.js

Add the following lines of code to your PostCSS file:

 const tailwindcss = require('tailwindcss');
 module.exports = {
     plugins: [

Inside your src folder create a folder, name it styles , this is where all your styles would be stored. Inside that folder, create a tailwind.css and an index.css file.

The index.css file is where we would be importing tailwind’s base styles and configurations, while the tailwind.css would contain the compiled output of the index.css.

How to inject tailwind’s components, utilities and base styles to your app

Add the following to your index.css file.


@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 baseThis injects Tailwind’s base styles, which is a combination of Normalize.css and some additional base styles.

For a complete reference of all the styles applied by Preflight, see this stylesheet.

If you’re using postcss-import, use this import instead:

@import "tailwindcss/base";

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

If you’re using postcss-import, use this import instead:

@import "tailwindcss/components";

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

Here’s an example:

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

Or if using a preprocessor or postcss-import:

@import "components/buttons";
@import "components/forms";

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

If using postcss-import, use this import instead:

@import "tailwindcss/utilities";

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

Here is an example:

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

.skew-45 { ... }

Or if using a preprocessor or postcss-import:

@import "utilities/background-patterns";
@import "utilities/skew-transforms";

Tailwind will swap all these directives out at build time and replace them with the CSS generated.

How to configure your app to build your CSS file

Configure your app to build the 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": "npm run build:style && react-scripts start",
  "build": "react-scripts build",
  "test": "react-scripts test",
  "eject": "react-scripts eject"

How 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 both 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 './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

After deletion it should become:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';

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

import React from 'react';
import logo from './logo.svg';
import './App.css';

After deletion it should become:

import React from 'react';
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


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:

<div className="App" >
    <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=""/>
        <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"/>
          <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>

What we’ve just done is we gave the div a width of 100% with w-full , we also set the max width with max-w-md for medium screens and larger.

We gave the form a white background with bg-white and gave it a border-radius to achieve the curved borders with border, px-8 and py-8 adds 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 font-size of .875rem to the label element with text-sm and made the element have 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


In this post, we’ve learned how to configure create-react-app to use Tailwind CSS. Tailwind has awesome documentation, so check it out for more information. You can also check out the repository for this tutorial on GitHub to scaffold your app.

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:

    : Full visibility into your web apps

    LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

    In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

    Anjolaoluwa Adebayo-Oyetoro Maker. Writes sometimes. playful most times. loves beautiful UIs

    18 Replies to “How to configure create-react-app to use Tailwind CSS”

    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

      > crm@0.1.0 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

      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 => [
      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”,

    Leave a Reply