Skip to main content

A pure Python Tailwind CSS class sorter that works with any HTML or CSS file, including Django templates and other template languages.

Project description

Tailwhip — Tailwind CSS class sorter

PyPI version Test Python Version License: MIT

Tailwhip is a pure Python Tailwind CSS class sorter that works with any HTML or CSS file — including Django templates and other templating languages.

Screenshot of Tailwhip

Why Tailwhip?

The official Prettier plugin for sorting Tailwind classes doesn’t play well with many template languages, such as Django. While there are Prettier plugins that add limited support for Jinja templates, they often require configuration workarounds or restrict what you can do with Prettier.

Tailwhip takes a more pragmatic approach. Instead of trying to parse and understand every possible template syntax, it focuses on sorting Tailwind classes reliably, and ignores class attributes that contain template syntax.

How it works:

  1. It finds all class="" attributes and @apply directives in the given files.
  2. It sorts the contained classes according to the official Tailwind CSS class order.
  3. If a class attribute contains template syntax (e.g., {{ ... }} or {% ... %}), Tailwhip leaves it untouched.

This approach ensures Tailwhip works across diverse environments — Django, Flask, Jinja2, or even custom templating engines — without breaking your templates or requiring complicated setup.

Usage

Tailwhip requires Python 3.11 or later.

$ uvx tailwhip [options] [filepath...]

# Find all .html and .css files in the templates directory
$ uvx tailwhip templates/

# Preview changes
$ uvx tailwhip templates/ -vv

# Actually apply changes
$ uvx tailwhip templates/ --write

# Sort classes in .scss files
$ uvx tailwhip "templates/**/*.scss"

# Standard glob patterns are supported
$ uvx tailwhip "static/**/*.{css,scss}" "templates/**/*.htm[l]"

# Use as a stdin/stdout filter (great for editor integrations!)
$ echo '<div class="p-4 m-2 bg-white">' | uvx tailwhip
<div class="m-2 p-4 bg-white">

# Pipe file content through tailwhip
$ cat template.html | tailwhip > sorted.html

You can also install it with pip and use it as a Python library:

$ pip install tailwhip

$ tailwhip templates/
$ python -m tailwhip templates/

See --help for all options and features.

Editor Integration

Tailwhip works as a STDIN/STDOUT filter, making it easy to integrate with text editors:

Shell:

$ tailwhip < file.html
$ cat file.html | tailwhip > file.html

Vim/Neovim:

" Sort classes in current file
:%!tailwhip

" Sort classes in visual selection
:'<,'>!tailwhip

Emacs:

;; Sort classes in region
(shell-command-on-region (region-beginning) (region-end) "tailwhip" t t)

VSCode: Configure as an external formatter or create a task that pipes selected text through tailwhip.

The stdin mode processes text and returns the result immediately, with no file I/O or configuration needed.

Pre-commit Hook

Tailwhip can automatically sort your Tailwind classes before every commit using pre-commit.

Add a .pre-commit-config.yaml file to your project:

repos:
 - repo: https://github.com/bartTC/tailwhip
   rev: v0.11  # Use the latest release tag
   hooks:
     - id: tailwhip

Customizing File Types

To include additional file types (like JSX, TSX, or template files), add a files pattern:

repos:
  - repo: https://github.com/bartTC/tailwhip
    rev: v0.11
    hooks:
      - id: tailwhip
        files: \.(html|htm|css|jsx|tsx|liquid)$

Configuration

Tailwhip works great out of the box with sensible defaults, but you can customize its behavior to match your project's needs. There are two ways to configure Tailwhip:

Option 1: pyproject.toml

Add a [tool.tailwhip] section to your project's pyproject.toml:

[tool.tailwhip]
# Increase verbosity to see detailed changes
verbosity = 2

# Customize file patterns to include JSX/TSX files
default_globs = [
    "**/*.html",
    "**/*.css",
    "**/*.jsx",
    "**/*.tsx",
]

# Add your custom Tailwind colors
custom_colors = ["brand", "accent", "company"]

# Add template syntax for your templating engine
skip_expressions = ["{{", "{%", "<%", "?", "[[", "]]"]

Option 2: Custom Configuration File

Create a tailwhip.toml file anywhere in your project and pass it via the --configuration flag:

# tailwhip.toml
verbosity = 3

default_globs = [
    "**/*.html",
    "**/*.css",
    "**/*.liquid",  # Shopify Liquid templates
]

custom_colors = ["primary", "secondary", "accent"]

skip_expressions = ["{{", "{%", "<%", "?", "{-"]  # Add Nunjucks syntax

Then use it with:

$ tailwhip templates/ --configuration=tailwhip.toml

Configuration Precedence

Settings are loaded in this order (later sources override earlier ones):

  1. Default values (built into Tailwhip)
  2. pyproject.toml ([tool.tailwhip] section)
  3. Custom config file (via --configuration flag)
  4. CLI arguments (e.g., --write, -v, --quiet)

CLI arguments always take precedence, so you can override any config value on the command line.

Available Configuration Options

For a complete list of all configuration options with detailed explanations, see the default configuration file. It includes:

  • Output settings: verbosity, write_mode
  • File discovery: default_globs
  • Template handling: skip_expressions
  • Sorting behavior: utility_groups, variant_groups
  • Color recognition: tailwind_colors, custom_colors
  • Pattern matching: class_patterns (advanced)

Most users only need to customize custom_colors and occasionally default_globs or skip_expressions. The sorting algorithm is based on Tailwind best practices and rarely needs modification.

Advanced: Custom Pattern Matching

Tailwhip uses configurable patterns to find and sort class attributes across different syntaxes. By default, it supports:

  • HTML class="..." attributes
  • CSS @apply ...; directives

You can add custom patterns for other frameworks (JSX, Vue, Svelte, etc.) by configuring class_patterns in your pyproject.toml or custom config file.

Important: Custom class_patterns replace (not extend) the defaults, just like any other configuration setting. You must include the default HTML and CSS patterns if you want to keep them:

# Example: Add JSX className support while keeping HTML class and CSS @apply
# In pyproject.toml, use [[tool.tailwhip.class_patterns]]
# In custom config file, use [[class_patterns]]

# Keep default: HTML class attribute
[[tool.tailwhip.class_patterns]]
name = "html_class"
regex = '''\bclass\s*=\s*(?P<quote>["'])(?P<classes>.*?)(?P=quote)'''
template = 'class={quote}{classes}{quote}'

# Keep default: CSS @apply directive
[[tool.tailwhip.class_patterns]]
name = "css_apply"
regex = '''@apply\s+(?P<classes>[^;]+);'''
template = '@apply {classes};'

# Add custom: JSX className
[[tool.tailwhip.class_patterns]]
name = "jsx_classname"
regex = '''\bclassName\s*=\s*(?P<quote>["'])(?P<classes>.*?)(?P=quote)'''
template = 'className={quote}{classes}{quote}'

Requirements:

  • Each pattern must have a (?P<classes>...) named group to capture the classes
  • The template field uses {classes} and any other named groups from the regex
  • Additional named groups are optional but must match between regex and template

See the configuration file for more examples and detailed documentation.

Changelog

See CHANGELOG.md for a complete list of changes and version history.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tailwhip-0.13.0.tar.gz (35.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tailwhip-0.13.0-py3-none-any.whl (37.1 kB view details)

Uploaded Python 3

File details

Details for the file tailwhip-0.13.0.tar.gz.

File metadata

  • Download URL: tailwhip-0.13.0.tar.gz
  • Upload date:
  • Size: 35.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tailwhip-0.13.0.tar.gz
Algorithm Hash digest
SHA256 495fab1055f26674423d38a50b19ad41ec1c59fdaf4688313427fcb6cd294376
MD5 7beb9ece2870b763f22cd49bd608c0cf
BLAKE2b-256 53867cae8b4358ff9c4ccafeaa26abe02860121a61eca1b6013d2b296b5a4378

See more details on using hashes here.

File details

Details for the file tailwhip-0.13.0-py3-none-any.whl.

File metadata

  • Download URL: tailwhip-0.13.0-py3-none-any.whl
  • Upload date:
  • Size: 37.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for tailwhip-0.13.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fbca00bb917b28ba8e1023c8abdc6ca241f16f49d27b2d4579bba3f43caeb916
MD5 7a2b3a8dc8baf65f5257a5d2055e7c8d
BLAKE2b-256 33afc9bd0dabc28b08883accbe77f71b943a1e372b4c9c03a37a0aba130fc6b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page