How to Setup Tailwind CSS with Django (Part 1)

Michael Yin

Last updated on November 03 2021

Table of Contents

Django Tailwind CSS, Alpine.js Tutorial Series:

  1. Introduction
  2. How to Setup Tailwind CSS with Django (Part 1)
  3. How to Setup Tailwind CSS with Django (Part 2)
  4. Optimize Tailwind CSS in Django
  5. Render Django Form with Tailwind CSS Style
  6. Integrate Alpine.js with Django (Part 1) (coming soon)
  7. Integrate Alpine.js with Django (Part 2) (coming soon)
  8. Build Task List with Tailwind CSS, Alpine.js and Django (coming soon)
  9. Django Form Validation in Tailwind Modal (Alpine.js) (coming soon)
  10. Django Form Validation in Tailwind Modal (Alpine.js + HTMX) (coming soon)
  11. How to deploy Django Tailwind CSS project with Docker (coming soon)

The source code is on Github/django-tailwind-alpine-htmx, demo is on Heroku

Objectives

By the end of this chapter, you should be able to:

  1. Learn to use django-tailwind to setup Tailwind CSS in Django project.
  2. Learn the basic workflow of the django-tailwind, and how to customize it.

django-tailwind

Django has great ecosystem and there are many django-xxx projects for us to use, let's first try https://github.com/timonweb/django-tailwind

Create Django project

$ mkdir django_tailwind_project && cd django_tailwind_project
$ python3 -m venv env
$ source env/bin/activate

You can also use other tools such as Poetry or Pipenv

Create requirements.txt

django==3.2
(env)$ pip install -r requirements.txt
(env)$ django-admin.py startproject django_tailwind_app .

You will see structure like this

.
├── django_tailwind_app
├── env
├── manage.py
└── requirements.txt

Now, let's get the project running on local env.

# create db tables
(env)$ python manage.py migrate
(env)$ python manage.py runserver

Check on http://127.0.0.1:8000/, and you should be able to see the Django welcome page

Install django-tailwind

Add django-tailwind to the requirements.txt

django==3.2
django-tailwind==2.2.1
(env)$ pip install -r requirements.txt

Update django_tailwind_app/settings.py to add 'tailwind' to INSTALLED_APPS

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'tailwind',               # new
]

Next, create a Tailwind CSS compatible Django app

(env)$ python manage.py tailwind init
# app_name: theme
# build mode: jit

As you can see, the theme app is generated

.
├── db.sqlite3
├── django_tailwind_app
├── env
├── manage.py
├── requirements.txt
└── theme                # new

Next, let's add the theme app to the INSTALLED_APPS

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'tailwind',
    'theme',                         # new
]

Add code below to the django_tailwind_app/settings.py

TAILWIND_APP_NAME = 'theme'

INTERNAL_IPS = [
    '127.0.0.1',
]

Let's install the npm dependency, below command will actually install npm packages under theme/static_src directory

If you have no nodejs installed, please install it first by using below links

  1. On nodejs homepage
  2. Using nvm I recommend this way.
$ node -v
v14.18.0
$ npm -v
6.14.15

(env)$ python manage.py tailwind install
theme
├── __init__.py
├── apps.py
├── static_src
│   ├── bs.config.js
│   ├── node_modules                   # new
│   ├── package-lock.json              # new
│   ├── package.json
│   ├── postcss.config.js
│   ├── src
│   └── tailwind.config.js
└── templates
    └── base.html
  1. node_modules contains the npm dependency packages.
  2. package-lock.json contains the versioned dependency tree.

Let's run the frontend development server

(env)$ python manage.py tailwind start


[Browsersync] Watching files...

warn - You have enabled the JIT engine which is currently in preview.
warn - Preview features are not covered by semver, may introduce breaking changes, and can change at any time.

Rebuilding...
Done in 343ms.

Django template

Let's do a quick test

Update django_tailwind_app/urls.py

from django.contrib import admin
from django.urls import path
from django.views.generic import TemplateView

urlpatterns = [
    path('', TemplateView.as_view(template_name="base.html")),     # new
    path('admin/', admin.site.urls),
]

Let's check theme/templates/base.html

{% load static tailwind_tags %}
<!DOCTYPE html>
<html lang="en">
    <head>
    <title>Django Tailwind</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        {% tailwind_css %}
    </head>

    <body class="bg-gray-50 font-serif leading-normal tracking-normal">
        <div class="container mx-auto">
            <section class="flex items-center justify-center h-screen">
                <h1 class="text-5xl">Django + Tailwind = ❤️</h1>
            </section>
        </div>
    </body>
</html>

{% tailwind_css %} will generate compiled CSS links

# please make sure "python manage.py tailwind start" is still running
(env)$ python manage.py runserver

Let's check http://127.0.0.1:8000/

django-tailwind workflow

Let's check theme/static_src

theme/static_src
├── bs.config.js
├── node_modules
├── package-lock.json
├── package.json
├── postcss.config.js
├── src
└── tailwind.config.js

Notes:

  1. Actually this is a Node.js project, the package.json contains all dependency and available commands
  2. node_modules contains the npm dependency packages.
  3. package-lock.json contains the versioned dependency tree.
  4. Other files are config and source files, you might need to edit them in some cases.
  5. For example, if you want to customize Tailwind, you need to edit theme/static_src/tailwind.config.js
  6. When we run python manage.py tailwind start, it will actually run npm run start in low level.
  7. The compiled css will be put at theme/static, and {% tailwind_css %} will load css there.

Pros

  1. django-tailwind can help us quickly import Tailwind CSS to Django without touching frontend config files.
  2. People who have no experience with frontend can still use it.

Cons

  1. The Node.js project created by django-tailwind does not have solution or any words about JS, so user who need to write JS will find a little hard to make it work together.

In the next chapter, I will talk about another way (python-webpack-boilerplate) to import Tailwind CSS to Django, which has better support for the JS.

Django Tailwind CSS, Alpine.js Tutorial Series:

  1. Introduction
  2. How to Setup Tailwind CSS with Django (Part 1)
  3. How to Setup Tailwind CSS with Django (Part 2)
  4. Optimize Tailwind CSS in Django
  5. Render Django Form with Tailwind CSS Style
  6. Integrate Alpine.js with Django (Part 1) (coming soon)
  7. Integrate Alpine.js with Django (Part 2) (coming soon)
  8. Build Task List with Tailwind CSS, Alpine.js and Django (coming soon)
  9. Django Form Validation in Tailwind Modal (Alpine.js) (coming soon)
  10. Django Form Validation in Tailwind Modal (Alpine.js + HTMX) (coming soon)
  11. How to deploy Django Tailwind CSS project with Docker (coming soon)

The source code is on Github/django-tailwind-alpine-htmx, demo is on Heroku


Michael Yin

Michael is a Full Stack Developer from China who loves writing code, tutorials about Django, and modern frontend tech.

He has published some ebooks on leanpub and tech course on testdriven.io.

He is also the founder of the AccordBox which provides the web development services.


Table of Contents

Frontend Guide For Python Dev

This FREE guide help Python developers to learn the Modern frontend tech

Learn More

Build Jamstack web app with Next.js and Wagtail CMS.

Read More

Subscribe

Get notified about new great Web Development Tutorial