2026-02-05 / Read time: ~5 min

Using Tailwind CSS in Flask – Modern Setup Guide (2026)

Step-by-step guide to integrating Tailwind CSS with Flask using the official CLI, automatic purging, and a smooth dev workflow.

Tailwind CSS has become the go-to utility-first CSS framework for rapid UI development. Pairing it with Flask — Python's lightweight web framework — gives you fast backend + beautiful, responsive frontends without fighting CSS files.

In this guide we'll set up a clean, production-ready integration using Tailwind CSS v4 (or v3) workflow with the official CLI, proper content scanning, and auto-rebuild during development.

Prerequisites

  • Python 3.10+
  • Node.js 18+ (with npm)
  • Basic Flask knowledge
my-flask-app/
├── app.py                 # or app/__init__.py if using app factory
├── tailwind.config.js
├── input.css              # or static/src/input.css
├── package.json
├── static/
│   └── css/
│       └── output.css     # compiled + purged Tailwind file
└── templates/
    └── index.html

Step 1: Create a Basic Flask App

# app.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def home():
    return render_template("index.html")

if __name__ == "__main__":
    app.run(debug=True)
<!-- templates/index.html -->
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Flask + Tailwind</title>
  <link href="{{ url_for('static', filename='css/output.css') }}" rel="stylesheet">
</head>
<body class="bg-gray-50 min-h-screen antialiased">
  <div class="container mx-auto px-4 py-16">
    <h1 class="text-5xl font-bold text-indigo-700 mb-6">
      Hello from Flask + Tailwind CSS
    </h1>
    <p class="text-xl text-gray-700 max-w-2xl">
      Rapidly build modern interfaces without ever leaving your Python comfort zone.
    </p>
  </div>
</body>
</html>

At this point nothing looks styled yet — let's add Tailwind.

Step 2: Initialize Node.js & Install Tailwind

In the root of your project:

npm init -y
npm install -D tailwindcss
npx tailwindcss init

Note (2026 update): Tailwind v4 no longer requires PostCSS by default when using the standalone CLI. The above is the simplest modern way.

Step 3: Configure tailwind.config.js

Update tailwind.config.js to scan your Jinja templates:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./templates/**/*.html",           // all Jinja templates
    "./app/templates/**/*.html",       // if using blueprints / app factory
  ],
  theme: {
    extend: {
      // Optional: customize colors, fonts, etc.
      colors: {
        primary: '#4f46e5',
      },
    },
  },
  plugins: [
    // require('@tailwindcss/typography'),
    // require('@tailwindcss/forms'),
  ],
}

Step 4: Create Input CSS File

Create input.css (you can put it in root or static/src/input.css):

/* input.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

Step 5: Build & Watch Tailwind CSS

Add these scripts to package.json:

{
  "scripts": {
    "build:css": "tailwindcss -i ./input.css -o ./static/css/output.css --minify",
    "watch:css": "tailwindcss -i ./input.css -o ./static/css/output.css --watch"
  }
}

Now run in separate terminals:

# Terminal 1 – Flask dev server
flask run --debug
# or python app.py

# Terminal 2 – Tailwind watcher
npm run watch:css

Every time you add/remove Tailwind classes in your templates, the output.css file updates automatically (and is purged to ~10–30 KB in production).

Bonus: One-command dev experience (using concurrently)

npm install -D concurrently

Update package.json scripts:

"dev": "concurrently \"npm run watch:css\" \"flask run --debug\""

Then just run:

npm run dev

Both Flask and Tailwind watch & reload happen together.

Production Build

Just run:

npm run build:css

The --minify flag ensures smallest possible file. Include static/css/output.css in your base template as usual.

Optional: Using DaisyUI, Flowbite, Preline, etc.

Many component libraries work great on top of Tailwind. Example with DaisyUI:

npm install -D daisyui@latest
// tailwind.config.js
plugins: [
  require('daisyui'),
],

Then use classes like btn btn-primary, card, navbar, etc.

Common Pitfalls & Tips

  • Classes not appearing? → Make sure the class is actually written in a .html file that is scanned (not in Python strings).
  • Large CSS file in dev? → Normal — Tailwind only purges in production builds or when --minify is used.
  • Jinja {% %} blocks → Tailwind scans them correctly as long as they're inside content paths.
  • Blueprints? → Add ./blueprints/*/templates/**/*.html to content array.
  • Tailwind v4 standalone CLI → If you want zero PostCSS: npx tailwindcss@latest init still works great.

Final Thoughts

Combining Flask + Tailwind gives you:

  • Lightning-fast prototyping
  • Zero context-switching between backend & frontend
  • Tiny production CSS bundles
  • Full control over design without fighting CSS specificity
#Flask #Tailwind CSS #Python #Web Development #Frontend

Share the blog

If you found this useful, broadcast it to the network.

POST_TO_X

Comments

03
de
dev_null 2026-02-01

The layout of this blog is incredibly clean. The sticky TOC works perfectly on my ultra-wide monitor.

de
design_system_fan 2026-02-01

Are you using DaisyUI for the theme switching as well? Would love to see a post on that.

an
anonymous_user 2026-01-31

Thanks for the share to X button logic, saved me a lot of time!