Skip to content

How to use TailwindCSS in a Cookiecutter Django project

A step by step tutorial on setting up TailwindCSS in a Django project generated by Cookiecutter

Hossein Kazemi
Hossein Kazemi
5 min read
How to use TailwindCSS in a Cookiecutter Django project

Motivation

TailwindCSS has found a growing fan-base among the developers who use Javascript frameworks such as React, GatsbyJS, Next.js.
But for the rest of us Bootstrap has been a go to option for years. In fact Cookiecutter Django configures Bootstrap out of the box for you.

Like many for a new project, I used Django Cookiecutter as my base, but this time I wanted to use those fancy styling from TailwindCSS in my project. After playing with the structure I managed to make it work the way I want it. As there was a lack of a proper tutorial on this, I felt this could be a good subject to write about.

Below are the steps you should follow:

1. Generate your Django project with Cookiecutter

# install cookie-cutter
pip install "cookiecutter>=1.7.0"

# generate your project
cookiecutter https://github.com/pydanny/cookiecutter-django

You will be asked a few questions, you can find a good explanation of all in Cookiecutter's docs. If you don't know the answer, go with the provided default. Don't over analyze.

2. Create a new folder structure for static files

In the root of your project create a folder called frontend and under it, create the same subfolders as you see in your apps static folder like below:

frontend/
 css/
 fonts/
 images/
 js/
 scss/

From now on this will be the place in which you put your static files. You will see the reason for this shortly.

3. Upgrade your Node version

Tailwind works with node version 12 above. What worked for me without much problems was version 14. Make sure you are upgrading your local version to 14 or if you are using Docker, change the version in the compose/local/node/Dockerfile. Your Dockerfile should look something like the following:

FROM node:14-stretch-slim

WORKDIR /app

COPY ./package.json /app

RUN npm install && npm cache clean --force

ENV PATH ./node_modules/.bin/:$PATH

Still with me?

4. Add the necessary dependencies to your package.json file

First add the following to dependencies in package.json. You don't need to use any dependency managers like npm or yarn at this stage. Just make sure you insert the following dependencies in the right version in the right place. To avoid conflicts, I suggested that you first start with the exact same dependencies mentioned below, make everything work and add other dependencies as you go:

  "dependencies": {
    "html-loader": "^1.3.2",
    "html-webpack-plugin": "^4.5.1",
  },
  "devDependencies": {
    "autoprefixer": "^10.2.4",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "^7.0.0",
    "css-loader": "^5.0.2",
    "dotenv-webpack": "^6.0.0",
    "file-loader": "^6.2.0",
    "mini-css-extract-plugin": "^1.3.6",
    "node-sass": "^5.0.0",
    "postcss": "^8.2.6",
    "postcss-loader": "^5.0.0",
    "purgecss-webpack-plugin": "^4.0.0",
    "sass-loader": "^11.0.1",
    "tailwindcss": "^2.0.3",
    "webpack": "^5.19.0",
    "webpack-cli": "^4.4.0",
    "webpack-dev-server": "^3.11.2"
  }

NOTE 1: It is important to know that TailwindCSS relies on PostCSS 8 and above. If are using packages different from the above, you need to make sure that there is no other dependency in your package.json that depends on PostCSS lower than version 8. To do the inspection use npm list or if you use yarn yarn list.

NOTE 2: Make sure there is no packages in your package.json that is related to Bootstrap

If you are already lost, just copy my config file from here: package.json and jump to step 7.

6.Replace Gulp with Webpack

As you saw in the previous step, we are introducing Webpack in the dependencies. This means that you need remove anything related to Gulp from your package.json file. Remove gulp-* dependencies and adjust the scripts section to look like below:

"scripts": {
    "start": "webpack serve --mode development",
    "build": "webpack --mode production"
}

Don't fall sleep yet!

7. Glue everything together with Webpack

As you saw we created a separate folder structure called frontend in which we are going to put our static files.
Now you might ask isn't the default static folder for this? It is a legit question, it actually is, however instead of we manually put our js, scss, etc files in there, Webpack will do this for us.

It simply reads everything in the frontend folder, does whatever magic is needed on those files such as optimization, post-processing, etc and put the results in the static folder for us so that Django can use them.

For this we create a Webpack configuration file called webpack.config.js. We tell Webpack where to start entry, where to find our static files and what to do with each of them based on their type rules and plugins. Explaining out Webpack works is outside the scope of this tutorial. You can copy my configurations directly from here: webpack.config.js

8. Add static files to your frontend folder

Now you need to create the necessary files in your frontend subfolder.
First, in the scss subfolder, create a file called app.scss and include the following:

@tailwind base;
@tailwind components;
@tailwind utilities;

This will serve as the main file for the styles. Webpack does its magic on it and converts it to a proper css file called app.css which you need to include in your base.html Django template.

Next, in the js subfolder, create a file called app.js and include the following as the first line:

import '../scss/app.scss';

This file serves as the entry point for Webpack. If you see the entry in the webpack.config.js file you can see that it points to this file. Webpack reads this file and sees that it should process a .scss file and does its magic based on what you've configured in the config file.

Finally, don't leave the fonts and images folder empty. My Webpack configs are not optimized to handle empty folders.

9. Delete your existing static folder

Make sure you've moved whatever file you want to frontend. Then remove the static folder as it will be generated by Webpack upon build. As a bonus add this folder (static) to your .gitignore file.

10. Add PostCSS config file

As mentioned above, TailwindCSS needs PostCSS. You'll need to add a file called postcss.config.js with the following content to the root of your project:

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  }
}

11. Add TailwindCSS config file

You can configure TailwindCSS the way you want it. However, to do this you need to create a file called tailwind.config.js in the root folder of your project and include the following:

// tailwind.config.js
module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}

You can read TailwindCSS documentation for more on this.

Still Awake?!

Now double check everything and if you use docker,first build the container using:

docker-compose -f local.yml build node

Then bring up the node container:

docker-compose -f local.yml up node

If everything is worked as planned, you should see the static folder generated for you include all the processed files from in your frontend folder. Now make sure you are using app.css and app.js in your base.html template file.

If you have any comments, or need help please do reach out to me on Twitter. And if this post helped you please don't forget to share it.

TutorialDjango