A Prettier plugin for Tailwind CSS that automatically sorts classes based on our recommended class order.

  • By Tailwind Labs
  • Last update: Jan 9, 2023
  • Comments: 14

prettier-plugin-tailwindcss

A Prettier plugin for Tailwind CSS v3.0+ that automatically sorts classes based on our recommended class order.

Installation

To get started, just install prettier-plugin-tailwindcss as a dev-dependency:

npm install -D prettier prettier-plugin-tailwindcss

This plugin follows Prettier’s autoloading convention, so as long as you’ve got Prettier set up in your project, it’ll start working automatically as soon as it’s installed.

Note that plugin autoloading is not supported when using certain package managers, such as pnpm or Yarn PnP. In this case you may need to add the plugin to your Prettier config explicitly:

// prettier.config.js
module.exports = {
  plugins: [require('prettier-plugin-tailwindcss')],
}

Resolving your Tailwind configuration

To ensure that the class sorting is taking into consideration any of your project's Tailwind customizations, it needs access to your Tailwind configuration file (tailwind.config.js).

By default the plugin will look for this file in the same directory as your Prettier configuration file. However, if your Tailwind configuration is somewhere else, you can specify this using the tailwindConfig option in your Prettier configuration.

Note that paths are resolved relative to the Prettier configuration file.

// prettier.config.js
module.exports = {
  tailwindConfig: './styles/tailwind.config.js',
}

If a local configuration file cannot be found the plugin will fallback to the default Tailwind configuration.

Compatibility with other Prettier plugins

To make this plugin work we had to use private Prettier APIs that can only be used by a single plugin at once. This means this plugin is incompatible with other Prettier plugins that are using the same APIs.

The most popular example we know of is prettier-plugin-svelte, which can't be installed at the same time as the Tailwind CSS plugin.

To work around this, we've bundled prettier-plugin-svelte directly into prettier-plugin-tailwindcss, so if you'd like to use this plugin with Svelte, just uninstall prettier-plugin-svelte and everything should work as expected.

If you discover any other incompatibilities, please share them in this issue and hopefully we can figure out a way to make it work.

Github

https://github.com/tailwindlabs/prettier-plugin-tailwindcss

Comments(14)

  • 1

    Incompatibility with other Prettier plugins

    To make this plugin work we had to use private Prettier APIs that can only be used by a single plugin at once. This means this plugin is incompatible with other Prettier plugins that are using the same APIs.

    This GitHub issue will serve as a place to keep track of which Prettier plugins are incompatible — and hopefully we'll eventually find some workarounds, or even a proper long term solution. 👍

    Known incompatibilities

    • @trivago/prettier-plugin-sort-imports
    • prettier-plugin-organize-imports
    • prettier-plugin-svelte (see below)
    • prettier-plugin-twig-melody

    prettier-plugin-svelte

    We've bundled the prettier-plugin-svelte directly into prettier-plugin-tailwindcss, so if you'd like to use this plugin with Svelte, just uninstall prettier-plugin-svelte and everything should work as expected.

    Workarounds

    While I have not tested it yet, @Mattinton provided one possible workaround in this comment.

  • 2

    Unable to get working VSCode formatOnSave

    Apologies if this is a naive question, not had much experience with how prettier & plugins work...

    I am trying to get this to work in a Svelte (+TS) setup, and it seems to run fine if I run the pnpm run format script across all files, but the plugin is not running on save with formatOnSave enabled in VSCode.

    Is there something I need to set to enable plugins when running within VSCode formatOnSave? Or is it because the formatOnSave uses the Prettier extension, so doesn't see the project installed plugin and would only work if a Tailwind Prettier extension appeared?

    VSCode settings.json "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode"

    Current set up... .prettierrc

    {
    	"useTabs": true,
    	"trailingComma": "none",
    	"semi": true,
    	"printWidth": 100,
    	"tailwindConfig": "./tailwind.config.cjs"
    }
    

    tailwind.config.cjs in the root of application (same as .prettierrc)

    module.exports = {
    	content: ["./src/**/*.{html,js,svelte,ts}"],
    	theme: {
    		extend: {}
    	},
    	plugins: []
    };
    

    .vscode/settings.json

    {
    	"[svelte]": {
    		"editor.formatOnSave": true,
    		"editor.defaultFormatter": "svelte.svelte-vscode"
    	}
    }
    

    Any guidance would be great!

  • 3

    Incompatible with `prettier-plugin-twig-melody`

    Hello,

    Regarding this part of the README.

    This means this plugin is incompatible with other Prettier plugins that are using the same APIs. ... If you discover any other incompatibilities, open an issue and hopefully we can figure out a way to make it work.

    This plugin does not work with *.twig files, with prettier-plugin-twig-melody

    prettier version: 2.5.1 prettier-plugin-twig-melody version: 0.4.6 tailwindcss version: 2.2.19

    My .prettierrc.js

    module.exports = {
      bracketSpacing: true,
      printWidth: 100,
      semi: true,
      singleQuote: true,
      tabWidth: 2,
      trailingComma: 'es5',
      useTabs: false,
      vueIndentScriptAndStyle: true,
      htmlWhitespaceSensitivity: 'ignore',
      twigPrintWidth: 100,
      twigMultiTags: ['html_element,end_html_element', 'with,endwith'],
      tailwindConfig: './tailwind.config.js'
    };
    

    Only the settings from the twig plugin are applied when running prettier, class names stay in the same order.

  • 4

    Add support for formatting `.astro` files

    Hello!

    I'm Erika from the Astro team. We love Tailwind and would love to have support for Astro files inside this plugin. As such, well, here's a PR that adds it 😄

    The support is pretty good, since we use other parsers for the different parts of the files, including expressions:

    ---
    ...
    ---
    
    <!-- This will format, this is what this PR adds! -->
    <div class="p-20 w-full bg-red-100"></div>
    
    <!-- This will format, since it's parsed and printed by `babel-ts` -->
    {<div class="p-20 w-full bg-red-100"></div>}
    
    <!-- This will format, since it's parsed and printed by Prettier's CSS parsers (so works for scss too) -->
    <style>
      h1 {
        @apply p-20 w-full bg-fuchsia-50;
      }
    </style>
    

    I hope we can get this to work, don't hesitate if there's anything needed from us to get this over the line!

    Thank you

  • 5

    [WIP] React Native "style" support

    Overview

    This PR is a quick stab at expanding the JSX attributes to include style for use in React Native. The use-case behind this is TailwindCSS is great and this plugin automates another standard that we would otherwise have to debate at some point. But, it doesn't yet support react native.

    Hoping you're open to the idea and thanks for the killer 💯 plugin 🔌

  • 6

    Will not format classes within Blade files.

    I'm using VS Code and I have everything installed as required, format on save is on.

    When I save, I get an error on the bottom that says Extension 'Prettier - code formatter' is configured as formatter but can not format 'Blade' files.

    I have this in my .prettierrc as noted in another issue, but it's not affecting anything:

    {
        "overrides": [
            {
                "files": "*.blade.php",
                "options": {
                    "parser": "html"
                }
            }
        ]
    }
    

    If I run npx prettier --check resources/views it states everything is formatted properly (which it's not)

    Interestingly, if I change a blade file to be a plain HTML file,format on save still does not do anything, but running npx prettier will then find the issues.

    What am I doing wrong?

    Is there no support for the formatter in blade files within a Laravel project?

  • 7

    Error formatting document

    Hey there! I'm getting this error in the VS code output console when trying to format a rather large .vue file. (SFC with script setup). I tried a bunch of files and this one isn't formatting properly, all others work super smooth. I can't share the exact file but I can provide some more details if necessary.

    prettier version: 2.5.1 prettier-plugin-tailwindcss version: 0.1.3 tailwindcss version: 3.0.16

    ["ERROR" - 8:15:05 AM] Error formatting document.
    TypeError: Cannot read property 'includes' of null
        at Lr (/Users/.../node_modules/prettier-plugin-tailwindcss/dist/index.js:145:943)
        at n (/Users/.../node_modules/prettier-plugin-tailwindcss/dist/index.js:145:2520)
        at n (/Users/.../node_modules/prettier-plugin-tailwindcss/dist/index.js:145:2956)
        at n (/Users/.../node_modules/prettier-plugin-tailwindcss/dist/index.js:145:2956)
        at n (/Users/.../node_modules/prettier-plugin-tailwindcss/dist/index.js:145:2956)
        at n (/Users/.../node_modules/prettier-plugin-tailwindcss/dist/index.js:145:2956)
        at Object.parse (/Users/.../node_modules/prettier-plugin-tailwindcss/dist/index.js:145:2363)
        at Object.parse$d [as parse] (/Users/.../node_modules/prettier/index.js:12975:19)
        at coreFormat (/Users/.../node_modules/prettier/index.js:14525:16)
        at formatWithCursor$1 (/Users/.../node_modules/prettier/index.js:14765:14)
        at /Users/.../node_modules/prettier/index.js:60959:12
        at Object.Success [as format] (/Users/.../node_modules/prettier/index.js:60979:12)
        at t.default.<anonymous> (/Users/.../.vscode/extensions/esbenp.prettier-vscode-9.1.0/src/PrettierEditService.ts:435:45)
        at Generator.next (<anonymous>)
        at s (/Users/.../.vscode/extensions/esbenp.prettier-vscode-9.1.0/dist/extension.js:1:7872)
    
  • 8

    feat: support properties and variable declarators

    This PR adds support for object properties and variable declarators within JavaScript-based languages, supporting either of the following syntaxes and their combinations:

    var className1 = 'sm:p-1 p-0';
    let className2 = "sm:p-1 p-0";
    const className3 = `sm:p-1 p-0`;
    
    let obj1 = {
      className: "sm:p-1 p-0",
    };
    
    let obj2 = {
      ["className"]: Math.random() >= 0.5 ? "sm:p-1 p-0" : "sm:p-2 p-1",
    };
    
  • 9

    Not working on HTML within .php files

    Hey guys,

    I installed the plugin and it's working like a charm on .html files (VSCode, Prettier extension + prettier php plugin).

    However, doesn't seem to apply the same changes if file's extension is .php.

    Am I missing something or currently HTML in PHP files is not supported?

  • 10

    seems to have no effect on class lists in template literals

    as an example:

    <div
      className={`
        flex
        flex-col
        justify-between
        flex-1
        p-6
        bg-gradient-to-br
        bg-white
        from-white
        to-gray-200
        dark:bg-gray-800
        dark:from-gray-800
        dark:to-gray-900
        dark:text-gray-50
        ${className}
      `}
    >
    

    plugin seems to not operate on these strings, flattening them into a single line seems to not have any effect either

    I have also tried randomly shuffling the class list to see if they were already sorted

  • 11

    Mismatch with Github Action using Prettier

    I'm using a Github action to format any code that my team pushes up using prettier. It's incredibly useful but I also have a local instance of Prettier installed via my node package.json and in VScode.

    There seems to be a mismatch in how the two versions of prettier handle a custom font class.

    VSCode returns this:

    <div class="font-inter flex w-full flex-row items-center justify-between"></div>
    

    My github action returns this:

    <div class="flex w-full flex-row items-center justify-between font-inter "></div>
    

    Is there any reason for this discrepancy?

    Actually, I just realized it is more than just the font classes. There are more classes where whatever ordering the styles aren't in sync. I do have this plugin in my dev dependencies so I t should be getting installed. Adding the commit log for this to show all the changes: https://github.com/fairdataihub/SODA-for-COVID-19-Research/commit/d4b3dc6642115bbb3f0ce3ba7c47038c2edcb563

  • 12

    Add prettier plugins to peer dependencies

    Fixes #112

    I tested it by publishing it to a private npm registry. You can test it for yourself (the yarn cache is checked into the repo): https://github.com/notpeelz/bug-repro-prettier-tw-sort-imports/tree/fixed

  • 13

    prettier-plugin-tailwindcss doesn't work with vscode

    prettier-plugin-tailwindcs: v0.2.1 Tailwind CSS: v3.2.4 Node.js: v18.12.1 Package Manager: pnpm v7.21.0 Operating System: Windows 11

    Describe your issue prettier-plugin-tailwindcss doesn't work with vscode and it's plugin Svelte for VS Code and Prettier - Code formatter; it won't format the *.svelte files (but it formats the html files);

    And with the svelte files, the "prettier" has taken effect, cause the prettier-plugin-organize-imports and prettier-plugin-css-order works fine,except prettier-plugin-tailwindcss...,so i think Is there anything that prevents tailwind formatting?...

    here is my .prettierrc

    {
        "plugins": ["prettier-plugin-svelte", "prettier-plugin-organize-imports", "prettier-plugin-css-order", "prettier-plugin-tailwindcss"],
        "pluginSearchDirs": false,
        "svelteSortOrder": "options-scripts-markup-styles",
        "svelteStrictMode": false,
        "svelteAllowShorthand": false,
        "svelteIndentScriptAndStyle": true,
        "organizeImportsSkipDestructiveCodeActions": true,
        "semi": true,
        "useTabs": false,
        "tabWidth": 4,
        "singleQuote": true,
        "trailingComma": "es5",
        "bracketSpacing": true,
        "bracketSameLine": true,
        "endOfLine": "lf",
        "quoteProps": "as-needed",
        "arrowParens": "always",
        "printWidth": 999999,
        "htmlWhitespaceSensitivity": "ignore",
        "singleAttributePerLine": false
    }
    
  • 14

    Vue `` classes are not sorted

    For the Vue components, only the attributes class and :class are sorted.

    https://github.com/tailwindlabs/prettier-plugin-tailwindcss/blob/01fe07a29aeefcc7933e5cec22a840ab07fd3918/src/index.js#L543

    However the Transition component in Vue has many other attributes that contain class names

      • enter-class
      • enter-active-class
      • enter-to-class
      • leave-class
      • leave-active-class
      • leave-to-class
      • v-enter-from
      • v-enter-active
      • v-enter-to
      • v-leave-from
      • v-leave-active
      • v-leave-to

    Can support be added to lint the order of classes inside these attributes as well?