DEV Community

Cover image for Optimize tailwind for a production ready React project
Neel
Neel

Posted on • Updated on

Optimize tailwind for a production ready React project

I have been working with tailwind for the past one year and it makes styling easier than ever. I am so spoiled by its flexibility that I cannot imagine working on a web application without using it. If you use tailwind for your projects, then you know how simple it is to work with it. You can make a div to look like a button with hover animation, shadow effects and every thing by throwing in just a few selectors.

ezgif.com-gif-maker

A CSS file with all the tailwind classes can be generated easily using the tailwind build command.

$ npx tailwindcss build -o src/index.css

   tailwindcss 2.0.2

   ๐Ÿš€ Building from default CSS... 

   โœ… Finished in 2.72 s
   ๐Ÿ“ฆ Size: 3.75MB
   ๐Ÿ’พ Saved to src/index.css
Enter fullscreen mode Exit fullscreen mode

The command will fill all the classes available in tailwind into the target index.css file. This CSS file can be imported to the index.js file of your react project to make it available globally for all the components.

If you take a look at the result of the build command, then you cannot miss but notice that the total size of the index.css file is 3.75MB. This is reasonable considering the fact that tailwind bundles more than 10,000 selectors but the question here is, "Do you really need all those classes in a production bundle?".

I have shipped 2 production ready react applications styled with tailwind and it hardly required more than 200 classes in total. Consider you are shipping a react application to production and if you import a complete tailwind CSS file, then it means that you are forcing the users to download 3.75MB of unnecessary data.

This is where the concept of purging comes into play. Instead of shipping your app with thousands of unwanted classes thereby increasing the application bundle's size, you can effectively leverage the tailwind purge feature to remove unused classes from the CSS file when bundling the final build of the application.

Let's see how it is done.

For this demo, I bootstrapped a sample react app with create-react-app. I have filled the default index.css file created by CRA with tailwind classes using the tailwind build command.

csd

I have created a new component named DemoButtonComponent.js and this is going to hold just 3 divs in it, styled with tailwind selectors.

code

If you take a look at the above component, it uses only 25 tailwind classes in total. For these 25 classes, we obviously do not need a CSS file which weighs over 3.75MB in size. So let's trim it down to make it production ready.

The first step is to generate a tailwind.config.js file. This can be done easily by running npx tailwindcss init from the root of the react project. The generated config file will have a few key-value pairs which can be configured based on project needs.

tw

For this demo, we are going to concentrate only on the purge: [] array. For a typical react project, I would recommend filling in the array with the following

module.exports = {
  purge: [
    "./public/**/*.html",
    "./src/**/*.js",
    "./src/**/*.jsx",
    "./src/**/*.tsx",
  ],
};

Enter fullscreen mode Exit fullscreen mode

This will look for the matching files within your project and will fill in only the required tailwind selectors into the index.css file (or the target CSS file you choose).

One important thing to keep in mind is that, tailwind will initiate purging only if the environment is production because in reality you will need the whole tailwind bundle during development. So the environment must be overridden to generate the optimized (or purged) CSS file.

# For linux / Mac / from git bash
$ export NODE_ENV=production && npx tailwindcss build -o src/index.css -c tailwind.config.js

# For windows 
$ set NODE_ENV=production 
$ npx tailwindcss build -o src/index.css -c tailwind.config.js
Enter fullscreen mode Exit fullscreen mode

Setting the environment variable NODE_ENV to production will make tailwind to build the CSS file with only the required classes. After running the script, the following is the result I got,

   tailwindcss 2.0.2

   ๐Ÿš€ Building from default CSS... 

   โœ… Finished in 2.52 s     
   ๐Ÿ“ฆ Size: 12.43KB
   ๐Ÿ’พ Saved to src/index.css
Enter fullscreen mode Exit fullscreen mode

The CSS file size has reduced significantly all the way from 3.75MB to 12.43KB and when you run npm run build after this, CRA will minify the CSS reducing the file size further.

โš ๏ธOne important thing to keep in mind is that the purgecss module used by tailwind will look for complete strings within the files. So if you have a scenario where the selectors are dynamically filled with partial strings, then those have to be avoided or modified to include the complete selector strings.

Example

This is not cool...

not-cool

This is totally cool...

cool

Read this article from tailwind docs to know more

That's is all for today... That is how you generate an optimized tailwind CSS for your production build.

Other reads

Building a doc Q&A chatbot with Next.js and GPT

Top comments (1)

Collapse
 
shrihankp profile image
Shrihan • Edited

I agree. I cannot imagine web development without Tailwind CSS. Coolest framework๐Ÿ˜Ž One more thing:

Using PostCSS + PurgeCSS + CSSNano, we can reduce the size even further. Install postcss(should already be installed, if tailwindcss is installed), postcss-cli, @fullhuman/postcss-purgecss(again, should be installed already, if installed tailwindcss), cssnano, autoprefixer(optional, recommended) as devDependencies.
Create a file called postcss.config.js and add the following:

const purgecss = require("@fullhuman/postcss-purgecss")
const cssnano = require("cssnano")
const tailwindcss = require("tailwindcss")

const tailwindConfig = require("./tailwind.config.js")
const autoprefixer = require("autoprefixer") //Make sure its installed to avoid nasty wobblers

module.exports = {
  tailwindcss(tailwindConfig),
  autoprefixer,
  purgecss({
    content: ['./public/*.html', './src/*.?s', './src/*.?sx'] // List every file that references the classes here. See the docs for PurgeCSS about details
  }),
  cssnano()
}
Enter fullscreen mode Exit fullscreen mode

After that, head over to the package.json file and add a script:

"build:css": "postcss css/styles.css -o css/dist.css"

Done. Run [packageManager] run build:css(where packageManager is one of npm or yarn)