How to add Tailwind into a React project in under a minute

Step 1 – How to set up React with CRA template

Install the CRA template first, by running:

npx create-react-app cool-demo

Step 2 – How to install NPM packages

Once it’s done, move on to the package.json and have a look at all the packages you have. Now, in order to add and configure tailwind, we need to add some packages for convenience.

These additional packages are:

yarn add tailwindcss postcss-cli autoprefixer @fullhuman/postcss-purgecss npm-run-all
  1. tailwindcss is the official npm package of tailwind and a key package for our project
  2. postcss-cli is a tool to transform styles with JS plugins
  3. autoprefixer is a postcss plugin that automatically does vendor prefixing from referring caniuse.com, which is such a blessing
  4. @fullhuman/postcss-purgecss is another postcss plugin that gets rid of all the unused CSS styles and results in smaller builds
  5. npm-run-all runs multiple build scripts at the same time or one after the other

Step 3 - How to set up Tailwind files

Now, it’s time to add the tailwind files to our project. We need to create two files: tailwind.css (says what stuff to include from tailwind library), and the second is tailwind.config.js (helps to configure tailwind according to our favor).

Create the above two files manually or by copy-pasting the command in the terminal below:

touch src/tailwind.css tailwind.config.js
  1. tailwind.css

This file will now be referred by the tailwindcss npm package, which will then generate a huge tailwind CSS file that includes all of the required utility classes.

But first, we need to add the types of classes we need. So add this to your tailwind.css file that was just created.

@tailwind base;
@tailwind components;
@tailwind utilities;
  1. tailwind.config.js

As explained above, you shall configure it yourself according to your needs. In my case, I prefer a desktop-first approach over mobile, which is totally opposite of the default in Tailwind.

See how to do this on the great docs by Tailwind.

module.exports = {
  purge: [],
  theme: {
    extend: {},
    screens: {
      xl: { max: "1279px" },
      // => @media (max-width: 1279px) { ... }

      lg: { max: "1023px" },
      // => @media (max-width: 1023px) { ... }

      md: { max: "767px" },
      // => @media (max-width: 767px) { ... }

      sm: { max: "639px" },
      // => @media (max-width: 639px) { ... }
    },
  },
  variants: {},
  plugins: [],
};

Protip: Instead of creating the tailwind.config.js yourself and copy-pasting any boilerplate, you can run this npx command for a skeleton setup to get started.

npx tailwindcss init

Also, pass the --full flag in the end to get the entire config file for tailwind.

npx tailwindcss init --full

Step 4 – How to create the postcss config

In order to configure postcss in our project with its additional plugins:

Create a file named postcss.config.js in your root folder or just copy the following to the terminal.

`touch` postcss.config.js

Then, update the file with our installed plugins and tailwind.

// Configure purgecss plugin
const purgecss = require("@fullhuman/postcss-purgecss")({
  // Specify the paths to all of the template files in your project
  content: [
    "./public/**/*.html",
    "./src/**/*.jsx",
    // etc.
  ],

  // This is the function used to extract class names from your templates
  defaultExtractor: content => {
    // Capture as liberally as possible, including things like `h-(screen-1.5)`
    const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [];

    // Capture classes within other delimiters like .block(class="w-1/2") in Pug
    const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || [];

    return broadMatches.concat(innerMatches);
  },
});

// Export all plugins. Our postcss should use
module.exports = {
  plugins: [
    require("tailwindcss"),
    require("autoprefixer"),
    ...(process.env.NODE_ENV === "production" ? [purgecss] : []),
  ],
};

If you’ve never heard of Purgecss, it’s another plugin for postcss that helps us trim the gigantic CSS file tailwind produces and narrow it down to only the classes/styles that we’ve included in our codebase.

Notice how we’re only using this plugin in production because, in development, it’s not much of a concern and can be slow to run, so we took care of that. The rest is tailwindcss and autoprefixer which, as mentioned, vendor prefixes our CSS stylings.

Step 5 – How to write the build scripts

Here is when we’ll use the npm-run-all package. So, basically, what we want to do is create some npm scripts that watch and compile our tailwind file whenever we make any changes to it.

So as not to confuse you, let me get to it one by one:

"build:tailwind": "postcss src/tailwind.css -o src/tailwind.generated.css"

You’ll need to run it once before publishing the build. All it does is take src/tailwind.css as an input file and output the CSS classes as required into tailwind.generated.css and -o for output.

"watch:tailwind": "postcss -w src/tailwind.css -o src/tailwind.generated.css"

The only difference between this and the code above is the -w flag. That is for watch and now, whenever you update the tailwind.css file, you’ll see the changes take effect instantly.

"start": "react-scripts start"
"dev": "run-p watch:tailwind start"

Now, by sticking them together, while running npm start, we can get our react to work. But, in order to watch for changes in the tailwind.css file, we need to add the run-p watch:tailwind command.

run-p is from our npm-run-all package. All it does is run our given scripts in parallel. Here we can run both npm run watch:tailwind and npm run start at the same time instead of switching terminals.

"prebuild": "npm run build:tailwind",
"build": "react-scripts build",

Ultimately, we need the build commands to deploy our app, so let’s add them. One thing you should know is that the pre keyword is special here, it means that the prebuild command must be executed before our build command is executed. Same with the prestart and start command.

There’s also a post keyword that does the opposite. For example, you would use post-build to run a script after running build script.

Here is the list of the same commands all together with some default ones for testing.

"scripts": {
        "build:tailwind": "postcss src/tailwind.css -o src/tailwind.generated.css",
        "watch:tailwind": "postcss -w src/tailwind.css -o src/tailwind.generated.css",
        "start": "react-scripts start",
        "dev": "run-p watch:tailwind start",
        "prebuild": "npm run build:tailwind",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
},

Now, we’re done with setting up scripts for tailwind to run, feel free to add any other script you need for your use case.

Step 6 – Include Tailwind in code

The worst thing that could happen while not working tailwind CSS code is if you forget to include the generated CSS file in the entry file to your project. So, go ahead and add this line to your index.js or App.js, wherever you feel is right and works for you.

import "./tailwind.generated.css";

Also, you might want to .gitignore this file as it’s a huge CSS file of utility classes and you won’t want to clutter your project on GitHub.

Let’s see if it works

Try adding some classes you know from tailwind, like font colors or margins, and see if it works.

I tweaked the App.js file and added text-yellow-400 and text-green-600 classes to the text elements. This is what I got:

widget

Additional setup

While researching for this shot, I encountered a package called cssnano, which has over 6m downloads on npm. You can check its website for an example.

cssano is another postcss plugin that removes all the weird comments we write in our CSS files and any whitespaces and minifies it for a further compressed bundle size.

Attributions:
  1. undefined by undefined
Copyright ©2024 Educative, Inc. All rights reserved