Setting Up Grunt and Tailwind CSS
Tags: tailwindcss, css, javascript, grunt
Published: 2019-10-19 11:31:01

[Tailwind CSS](https://www.tailwindcss.com "https://www.tailwindcss.com") has been getting a lot of love recently at meetups, conferences and from the Web Development Twitterati.

With a site re-skin on the horizon. I was keen to find out if I could use Tailwind CSS to move on from Bootstrap and build my own fully customised UI library.

## What is this Tailwind CSS thing you speak of ?

"A utility-first CSS framework for rapidly building custom designs.

Tailwind CSS is a highly customizable, low-level CSS framework that gives you all of the building blocks you need to build bespoke designs without any annoying opinionated styles you have to fight to override."

Check them out at [https://www.tailwindcss.com](https://tailwindcss.com "https://tailwindcss.com").

## Why Grunt?

The site that I'll be re-skinning uses a series of Grunt tasks to compile CSS, JS, Minification etc. It's not the most modern of setups, but it still works great.

I was reading through Tailwind CSS' great [documentation](https://tailwindcss.com/docs/installation "Tailwind CSS Documentation"). Unfortunately, there didn't seem to be an example for setting up Grunt.

I love a build tool challenge, so with a fresh coffee and a couple of spare hours. I decided to work it out.

The guides provided for Gulp and Webpack etc pointed me in the right direction.

This is what you need to do.

## 1. Install the following packages
```
npm install tailwindcss --save-dev
```
``` 
npm install grunt-postcss --save-dev
```
``` 
npm install autoprefixer --save-dev
```

## 2. Gruntfile.js configuration

```js
module.exports = function (grunt) {
  grunt.initConfig({
    // get the configuration info from package.json
    pkg: grunt.file.readJSON('package.json'),

    // PostCSS - Tailwindcss and Autoprefixer
    postcss: {
      options: {
        map: true, // inline sourcemaps
        processors: [
          require('tailwindcss')(),
          require('autoprefixer')({ browsers: 'last 2 versions' }) // add vendor prefixes
        ]
      },
      dist: {
        expand: true,
        cwd: 'ui/src/tailwindcss/',
        src: ['**/*.css'],
        dest: 'ui/dist/tailwindcss/',
        ext: '.css'
      }
    },

    // Watch for changes and run Tasks
    watch: {
      postcss: {
        files: 'ui/src/tailwindcss/**/*.css',
        tasks: ['compile-tailwindcss'],
        options: {
          interrupt: true
        }
      }
    }
  })

  // Load Grunt Plugins
  grunt.loadNpmTasks('grunt-contrib-watch')
  grunt.loadNpmTasks('grunt-postcss')

  // Register Tasks
  grunt.registerTask('compile-tailwindcss', ['postcss'])

  // Resgiter Watcher Tasks
  grunt.registerTask('watch-tailwindcss', ['watch:postcss'])
}
```

## 3. Create a tailwind.css file in your src directory

Add the following code to your tailwind.css file

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

## 4. Compile Tailwind CSS

To manually compile your Tailwind CSS files:
``` 
    grunt compile-tailwindcss
```
To compile your Tailwind CSS files on src changes:
``` 
   grunt watch-tailwindcss
```

## 5. Add the compiled CSS file to your web pages
```
<link href="/ui/dist/tailwindcss/tailwind.css" rel="stylesheet" type="text/css">
```

## And we're done!

If the development gods were smiling upon you and everything worked as it should. You should now be able to follow the Tailwind CSS documentation and start playing with their great utility functions.

In a very short space of time. I have managed to replicate the entire responsive layout of the site I will be reskinning.

How many lines of custom CSS code have I had to write so far?...Zero!

How many !important overrides have I been forced to write so far?...Zero!

This makes me happy.

## Useful URLS

[https://www.tailwindcss.com](https://www.tailwindcss.com "https://www.tailwindcss.com")

[https://www.npmjs.com/package/tailwindcss](https://www.npmjs.com/package/tailwindcss "https://www.npmjs.com/package/tailwindcss")

[https://www.npmjs.com/package/grunt-postcss](https://www.npmjs.com/package/grunt-postcss "https://www.npmjs.com/package/grunt-postcss")

[https://www.npmjs.com/package/autoprefixer](https://www.npmjs.com/package/autoprefixer "https://www.npmjs.com/package/autoprefixer")