Prettier 26 ๐จ prettier-plugin-tailwindcss โ Class sorting for Tailwind
The prettier-plugin-tailwindcss plugin does one thing: it sorts Tailwind CSS classes in the order that Tailwind’s own tooling recommends. It is not a linter, and it does not detect unused or conflicting classes. It reads the class strings in your markupโthe class attribute, the framework-specific equivalents like className, and the function calls you configureโand rewrites them so that the order is consistent across the codebase . The plugin was built by the Tailwind Labs team, and it is the official sorting mechanism that the Tailwind documentation points to.
The plugin’s value is the elimination of order debates. Two developers can write the same set of classes in different orders, and the rendered result is identical, but the diffs are noisy and the code review comments are about preference rather than substance. The plugin makes the order deterministic, which means the diff is empty when the classes are the same and the review is about the classes that actually changed. The sorting is based on Tailwind’s recommended order, which is the order that the Tailwind team uses in its own documentation and examples .
Key point: The plugin requires Prettier v3 and is ESM-only as of v0.5.x. It needs access to the Tailwind configurationโtailwindStylesheet for Tailwind v4, tailwindConfig for Tailwind v3โto sort custom classes correctly. It sorts the class attribute and the framework equivalents by default, and the tailwindAttributes and tailwindFunctions options extend the scope to custom attributes and function calls.
Why the plugin exists
The order-consistency problem. Tailwind’s utility classes are order-independent in the CSS output. flex p-4 and p-4 flex produce the same styles. But the source code is read by humans, and a consistent order makes the classes easier to scan. The plugin enforces the order that Tailwind’s own documentation uses, which means the codebase matches the examples that developers learn from. The plugin’s README states that it sorts “based on our recommended class order” .
The configuration-access problem. A project that customizes Tailwindโa custom color, a custom spacing scale, a custom utilityโneeds the plugin to know about those customizations, or the sorting will place the custom classes in the wrong position. The plugin reads the Tailwind configuration to build the sort order. For Tailwind v3, the configuration is the tailwind.config.js file, and the tailwindConfig option points to it. For Tailwind v4, the configuration lives in the CSS entry point, and the tailwindStylesheet option points to it . Without the configuration, the plugin falls back to the default Tailwind order, and the custom classes are sorted as if they were unknown.
The ESM-only constraint. As of v0.5.x, the plugin requires Prettier v3 and is ESM-only. It cannot be loaded with require(). A CommonJS Prettier configuration must either switch to the ESM syntax or use a dynamic import. The migration guide in the plugin’s repository explains the upgrade path . The constraint is a consequence of Prettier 3’s ESM-first design, and it is the first thing to check when the plugin does not load.
The trade-off. The plugin adds a dependency and a Prettier configuration entry. The dependency is a dev dependency, and the configuration entry is a single line in .prettierrc. The plugin runs during prettier --write and during the editor’s format-on-save, so the sorting is applied consistently. The cost is the dependency and the configuration, and the benefit is the elimination of the order inconsistency.
a. The installation and the configuration
The installation is two packages: Prettier and the plugin. The plugin is a dev dependency.
# Install Prettier and the plugin.
npm install -D prettier prettier-plugin-tailwindcss
The configuration is a plugins entry in .prettierrc. The plugin is added to the array, and Prettier loads it when it runs.
// .prettierrc โ the plugin configuration
{
"plugins": ["prettier-plugin-tailwindcss"]
}
The JavaScript configuration form is the alternative, and it provides the type hints for the plugin options.
// prettier.config.js โ the typed configuration
/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
export default {
plugins: ["prettier-plugin-tailwindcss"],
};
The plugin’s README states that the configuration is the plugins array, and the JavaScript form is the one that provides the IntelliSense for the plugin’s options . The .prettierrc form is the simpler one for a project that does not need the types.
b. The Tailwind configuration options
The plugin needs the Tailwind configuration to sort custom classes correctly. The option differs between Tailwind v3 and Tailwind v4.
// .prettierrc โ Tailwind v4
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindStylesheet": "./resources/css/app.css"
}
For Tailwind v4, the tailwindStylesheet option points to the CSS file that contains the @import "tailwindcss" and the @theme block. The path is resolved relative to the Prettier configuration file . The CSS file is the entry point that includes the theme and the custom utilities, and the plugin reads it to build the sort order.
// .prettierrc โ Tailwind v3
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindConfig": "./styles/tailwind.config.js"
}
For Tailwind v3, the tailwindConfig option points to the tailwind.config.js file. The path is resolved relative to the Prettier configuration file. If the file is not found, the plugin falls back to the default Tailwind configuration . The fallback is the reason a project with a custom configuration may see the custom classes sorted incorrectly: the plugin did not find the configuration, and it used the default order.
c. The custom attributes and function calls
The plugin sorts the class attribute and the framework-specific equivalentsโclassName in React, :class in Vue, [ngClass] in Angularโby default. The tailwindAttributes option extends the scope to custom attributes.
// .prettierrc โ the custom attributes
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindAttributes": ["myClassList", "/data-.*/"]
}
The tailwindAttributes array accepts attribute names and regular expressions. The regex pattern is enclosed in forward slashes, and the plugin sorts any attribute that matches . The pattern /data-.*/ matches every attribute that starts with data-, which is the mechanism for a project that stores classes in data attributes.
The tailwindFunctions option extends the scope to function calls and tagged template literals. The array lists the function names that the plugin should treat as class-list containers.
// .prettierrc โ the function calls
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindFunctions": ["clsx", "tw"]
}
The clsx function is the common case: the plugin sorts the string arguments and the object keys that are passed to clsx() . The tw function is the tagged template case: the plugin sorts the classes inside the template literal that is tagged with tw . The tagged template pattern is the one that twrnc and similar libraries use, and the tailwindFunctions option is the mechanism that tells the plugin to treat the tag as a class list.
Complete Example Session
// ============================================
// PART 1: THE INSTALLATION
// ============================================
// npm install -D prettier prettier-plugin-tailwindcss
// ============================================
// PART 2: THE BASIC CONFIGURATION
// ============================================
// .prettierrc
{
"plugins": ["prettier-plugin-tailwindcss"]
}
// The plugin sorts the class attribute and the
// framework-specific equivalents.
// ============================================
// PART 3: THE TAILWIND V4 CONFIGURATION
// ============================================
// .prettierrc
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindStylesheet": "./src/styles/global.css"
}
// The tailwindStylesheet points to the CSS entry point.
// The plugin reads the theme and custom utilities.
// ============================================
// PART 4: THE TAILWIND V3 CONFIGURATION
// ============================================
// .prettierrc
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindConfig": "./styles/tailwind.config.js"
}
// The tailwindConfig points to the JavaScript config.
// The plugin reads the custom colors and spacing.
// ============================================
// PART 5: THE CUSTOM ATTRIBUTES
// ============================================
// .prettierrc
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindAttributes": ["myClassList", "/data-.*/"]
}
// The plugin sorts the myClassList attribute
// and any attribute that starts with data-.
// ============================================
// PART 6: THE FUNCTION CALLS
// ============================================
// .prettierrc
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindFunctions": ["clsx"]
}
// The plugin sorts the classes inside clsx() calls.
import clsx from 'clsx';
const classes = clsx('rounded bg-blue-500 px-4 py-2 text-base text-white');
// The output is the sorted order.
// ============================================
// PART 7: THE TAGGED TEMPLATE
// ============================================
// .prettierrc
{
"plugins": ["prettier-plugin-tailwindcss"],
"tailwindFunctions": ["tw"]
}
// The plugin sorts the classes inside tw`...`.
import tw from 'twrnc';
const classes = tw`bg-white p-4 dark:bg-black`;
// The output is the sorted order.
// ============================================
// PART 8: THE ESM CONSTRAINT
// ============================================
// As of v0.5.x, the plugin requires Prettier v3.
// The plugin is ESM-only.
// A CommonJS config must use the ESM syntax or dynamic import.
// ============================================
// PART 9: THE COMPATIBILITY
// ============================================
// The plugin is incompatible with some other Prettier plugins
// that use the same Prettier APIs.
// The plugin's README lists the workarounds.
// The plugin must be loaded last in the plugins array.
// ============================================
// PART 10: THE VERIFICATION
// ============================================
// [ ] The plugin is installed as a dev dependency.
// [ ] The plugin is in the Prettier plugins array.
// [ ] The tailwindStylesheet (v4) or tailwindConfig (v3) is set.
// [ ] The tailwindAttributes are set for custom attributes.
// [ ] The tailwindFunctions are set for function calls.
// [ ] The plugin is loaded last if other plugins are used.
// [ ] The Prettier version is v3 or later.
The ten parts covered the installation, the basic configuration, the Tailwind v4 configuration, the Tailwind v3 configuration, the custom attributes, the function calls, the tagged template, the ESM constraint, the compatibility, and the verification. The through-line is that the plugin is a sorting mechanism, and the configuration is the scope of the sorting.
Quick Reference
The installation
| Package | Command |
|---|---|
| Prettier + plugin | npm install -D prettier prettier-plugin-tailwindcss |
The configuration options
| Option | Tailwind version | Purpose |
|---|---|---|
plugins | Both | The plugin entry |
tailwindStylesheet | v4 | The CSS entry point |
tailwindConfig | v3 | The JS config path |
tailwindAttributes | Both | Custom attributes |
tailwindFunctions | Both | Function calls |
The ESM constraint
| Version | Requirement |
|---|---|
| v0.5.x+ | Prettier v3, ESM-only |
| Older | Prettier v2, CommonJS |
Best Practices
โ Do This:
// Set the Tailwind configuration path
"tailwindStylesheet": "./src/styles/global.css" // โ
// Extend the scope to custom attributes
"tailwindAttributes": ["myClassList", "/data-.*/"] // โ
// Extend the scope to function calls
"tailwindFunctions": ["clsx", "tw"] // โ
โ Don’t Do This:
// Use require() with the ESM-only plugin
const plugin = require('prettier-plugin-tailwindcss'); // โ
// Omit the Tailwind configuration path
// The custom classes are sorted with the default order. // โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| The plugin does not load | Prettier v2 or CommonJS config | Use Prettier v3 and ESM |
| The custom classes are not sorted | The Tailwind config is not found | Set tailwindStylesheet or tailwindConfig |
| The classes are not sorted in a custom attribute | The attribute is not in tailwindAttributes | Add the attribute name or regex |
The classes are not sorted in clsx() | The function is not in tailwindFunctions | Add the function name |
| The plugin conflicts with another plugin | The plugin must be loaded last | Put it last in the plugins array |
Real-World Examples
1. The basic config
{ "plugins": ["prettier-plugin-tailwindcss"] }
2. The Tailwind v4 config
{ "plugins": ["prettier-plugin-tailwindcss"], "tailwindStylesheet": "./src/app.css" }
3. The Tailwind v3 config
{ "plugins": ["prettier-plugin-tailwindcss"], "tailwindConfig": "./tailwind.config.js" }
4. The custom attribute
{ "tailwindAttributes": ["myClassList"] }
5. The regex attribute
{ "tailwindAttributes": ["/data-.*/"] }
6. The function call
{ "tailwindFunctions": ["clsx"] }
7. The tagged template
{ "tailwindFunctions": ["tw"] }
8. The ESM config
/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
export default { plugins: ["prettier-plugin-tailwindcss"] };
9. The plugin order
{ "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"] }
10. The sorting
// Before: <div className="p-4 flex bg-white" />
// After: <div className="flex bg-white p-4" />
Visual
The Plugin’s Scope
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WHAT THE PLUGIN SORTS โ
โ โ
โ Default: โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ class attribute โ โ
โ โ className (React) โ โ
โ โ :class (Vue) โ โ
โ โ [ngClass] (Angular) โ โ
โ โ @apply directives โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Extended: โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ tailwindAttributes โ Custom attributes โ
โ โ tailwindFunctions โ Function calls and templates โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Configuration Path
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ THE PLUGIN NEEDS THE TAILWIND CONFIG โ
โ โ
โ Tailwind v4: โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ tailwindStylesheet โ โ ./src/app.css โ
โ โ โ The CSS entry point โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Tailwind v3: โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ tailwindConfig โ โ ./tailwind.config.js โ
โ โ โ The JS config โ
โ โโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Without the config, the custom classes are sorted โ
โ with the default order. โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The ESM Constraint
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ v0.5.x REQUIRES PRETTIER v3 AND ESM โ
โ โ
โ โ
ESM config: โ
โ export default { plugins: ["prettier-plugin-tailwindcss"] } โ
โ โ
โ โ CommonJS config: โ
โ module.exports = { plugins: [require("...")] } โ
โ โ
โ The plugin cannot be loaded via require(). โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Package | prettier-plugin-tailwindcss |
| Requires | Prettier v3, ESM-only (v0.5.x+) |
| Default scope | class, className, :class, [ngClass], @apply |
| Tailwind v4 option | tailwindStylesheet |
| Tailwind v3 option | tailwindConfig |
| Custom attributes | tailwindAttributes |
| Function calls | tailwindFunctions |
| Plugin order | Must be last if other plugins are used |
Key takeaways:
- The plugin sorts classes in Tailwind’s recommended order. It is the official sorting mechanism, and it eliminates the order inconsistency that makes diffs noisy and reviews about preference rather than substance .
- The plugin needs the Tailwind configuration. For Tailwind v4, the
tailwindStylesheetoption points to the CSS entry point. For Tailwind v3, thetailwindConfigoption points to the JavaScript config. Without the configuration, the custom classes are sorted with the default order . - The
tailwindAttributesoption extends the scope to custom attributes. The array accepts attribute names and regular expressions. The regex pattern is enclosed in forward slashes . - The
tailwindFunctionsoption extends the scope to function calls and tagged templates. Theclsxfunction is the common case, and thetwtag is the tagged template case . - The plugin is ESM-only as of v0.5.x. It requires Prettier v3, and it cannot be loaded with
require(). A CommonJS configuration must switch to the ESM syntax or use a dynamic import .
Remember: The prettier-plugin-tailwindcss plugin is a sorting mechanism, not a linter. It reads the class strings and rewrites them in Tailwind’s recommended order. The configuration is the scope: the tailwindStylesheet or tailwindConfig tells the plugin where the custom classes are defined, and the tailwindAttributes and tailwindFunctions options tell it where the class strings live. The plugin is ESM-only, and it must be loaded last if other Prettier plugins are used. The sorting is applied during prettier --write and during format-on-save, and the result is a codebase where the class order is consistent and the diffs are about substance.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!