Using Tailwind CSS with Django 3.x

When it comes to using elements of modern front-end stacks in Django, there is more than one way. The key is to find the configuration that combines best practices, and leverages each tool for what it’s good at.

Many examples online show how to add Tailwind inside a full fledged front-end stack, often with a complex build system setup to handle things such as ES6, Typescript, Vue or React, Sass/less, etc.

But you don’t need a complex build system to leverage the full power of Tailwind. In this tutorial, I’m going to describe a very simple and straight forward way to use Tailwind with Django.

Create a new Django app

I prefer to keep ma front-end code contained to a single Django app, which is convenient for most Django websites.

Create a new app called theme.

django-admin startapp theme

In your settings.py , make sure you add the newly created app to your INSTALLED_APPS

INSTALLED_APPS = [
    ...
    'django.contrib.staticfiles',
    'theme',
]
<root>
├── db.sqlite3
├── manage.py
├── requirements.txt
├── theme
    ├── __init__.py
    ├── apps.py
    ├── views.py
    ├── models.py
    └── templates/
        └── theme
            └── index.html

Install Tailwind & necessary dependencies

npm init -y
npm install tailwindcss autoprefixer cssnano postcss postcss-cli

# or

yarn init
yarn add tailwindcss autoprefixer cssnano postcss postcss-cli

For an optimal setup, we’ll be using Tailwind as a postcss plugin. This will allow us to combine it with a couple more postcss plugin, namely: autoprefixer and cssnano.

Run npx tailwindcss init -p which will create tailwind.config.js and postcss.config.js

Let’s tell tailwind where to find the used CSS classes:

// tailwind.config.js
module.exports = {
  purge: ["templates/**/*.html"],
  darkMode: false,
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
};

Let’s make sure we run cssnano only in production:

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    cssnano: ctx.env === "production" ? {} : false,
  },
};

Create a styles.css:

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

/* custom classes */

.btn {
    @apply font-bold py-2 px-4 rounded;
}

.btn-blue {
    @apply bg-blue-500 text-white;
}

We’re ready to compile our styles.css .

1, 2, 3 build!

In your package.json, add the following scripts:

// package.json

"scripts": {
   "theme:dev": "postcss styles.css -w -d static/theme/ --verbose",
   "theme:build": "NODE_ENV=production postcss styles.css -d static/theme/ --verbose",
},

assuming you’re serving your app static files theme/static/theme/ to comply with Django’s best practices.

Now running the build should be as simple as:

$ npm run theme:build

Processing styles.css...
Finished styles.css in 1.02 s

Use anywhere

<!-- index.html -->

{% load static %}

<html>
  <head>

    <link href="{% static 'theme/style.css' %}" />
    ...
  </head>

  <body>
    ...
  </body>
</html>