prettier-plugin-tailwindcss: 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.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 52
  • Comments: 73 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Hey folks! 👋

So just an update on the Prettier plugin compatibility situation. We’ve just released a new beta version of prettier-plugin-tailwindcss which improves (or at least we hope it does 😅) compatibility with specific other Prettier plugins, including:

  • prettier-plugin-svelte
  • prettier-plugin-astro
  • @trivago/prettier-plugin-sort-imports
  • prettier-plugin-organize-imports

We’ve taken a new approach with our Prettier plugin where we no longer bundle any third-party Prettier plugins (including the Svelte plugin — more on that below). And, through a safe list, we’ve explicitly added support for the above plugins which currently have known incompatibilities.

We’ve done this by automatically detecting if one of these plugins is installed and enabled in your project, and if it is, we do some magic behind the scenes in our plugin to make sure these plugins still work.

The one gotcha with this approach is that Prettier plugin autoloading is unreliable, because our plugin must come last in the list of plugins. For this reason, you’ll need to explicitly disable the pluginSearchDirs option, and define each of your Prettier plugins in the plugins array:

// .prettierrc
{
  // ..
  "plugins": [
    "prettier-plugin-astro",
    "prettier-plugin-organize-imports",
    "prettier-plugin-tailwindcss" // MUST come last
  ],
  "pluginSearchDirs": false
}

For Svelte users, we no longer bundle the prettier-plugin-svelte plugin within our plugin, so you’ll need install and enable it using the instructions above.

For Astro users, this new release supports prettier-plugin-astro, which you can install in the same way.

We’ve released this updated plugin as a beta version since we’re not 100% sure on this approach quite yet, and would really appreciate your help testing it out. You can install it using the beta tag:

npm install prettier-plugin-tailwindcss@beta

Let me know how it goes! 💪

@rwwagner90 It’s not that this plugin is incompatible with prettier-plugin-astro, but this plugin only works with a few extensions (such as vue, html, etc).

Would it be possible to add astro support?

I found a new workaround to make @trivago/prettier-plugin-sort-imports and prettier-plugin-tailwindcss work at the same time in React+TypeScript(work in vscode🎉).

  1. if you do not have prettier.config.js, create a file and move your config to `prettier.config.js
  2. copy to prettier.config.js.
const pluginSortImports = require("@trivago/prettier-plugin-sort-imports")
const pluginTailwindcss = require("prettier-plugin-tailwindcss")

/** @type {import("prettier").Parser}  */
const myParser = {
  ...pluginSortImports.parsers.typescript,
  parse: pluginTailwindcss.parsers.typescript.parse,
}

/** @type {import("prettier").Plugin}  */
const myPlugin = {
  parsers: {
    typescript: myParser,
  },
}

module.exports = {
  plugins: [myPlugin],
  // your settings
}
  1. it will look like this
Sample Code
import { fuga } from "./hoge"
import { Alert } from "~/components/atoms/Alert"


type Props = {}

export function Component(props: Props) {
  return (
    <div className="flex items-center justify-center w-[200px] h-64">
      <Alert />
    </div>
  )
}

// after
/*
config = {
  plugins: [hackedPlugin],
  tabWidth: 2,
  semi: false,
  printWidth: 120,
  arrowParens: "always",
  importOrder: ["^[~/]", "^[../]", "^[./]"],
  importOrderSeparation: true,
}
*/

import { Alert } from "~/components/atoms/Alert"

import { fuga } from "./hoge"

type Props = {}

export function Component(props: Props) {
  return (
    <div className="flex h-64 w-[200px] items-center justify-center">
      <Alert />
    </div>
  )
}

References.

Underlying problem

Underlying problem

After some investigation, I suspect that there is a problem with prettier core getParsers().

https://github.com/prettier/prettier/blob/cd9955f1431ca3814ea9b713aa7275ceefa980d9/src/main/parser.js#L15-L25

For example

// prettier.config.js
const APlugin = {
  parsers: {
    typescript: ... ,
  },
}

const BPlugin = {
  parsers: {
    typescript: ... ,
  },
}

module.exports = {
  plugins: [APlugin, BPlugin],
  // ...
}

APlugin does not work when formatted with a ts file, and only BPlugin works.

I assume this is because the parsers in getParsers() are overwritten for each plugin. I am currently investigating.

Hello everyone, another update, we’ve just released v0.2.0, which includes all these plugin compatibility fixes.

You can install it using npm:

npm install prettier-plugin-tailwindcss@latest

We’ve also updated the readme to list all the Prettier plugins that we’ve added explicit support for:

https://github.com/tailwindlabs/prettier-plugin-tailwindcss#compatibility-with-other-prettier-plugins

With all this complete, I am going to close this issue as resolved. Thanks to everyone here for sharing information about incompatible plugins with us! 🙏

Seems this one might be incompatible as well https://github.com/withastro/prettier-plugin-astro

I originally opened issue #26 about prettier-plugin-organize-imports - in that specific case, I’m able to work around the incompatibility for now by monkey-patching prettier-plugin-tailwindcss so that each overlapping parser uses the preprocess function from prettier-plugin-organize-imports, like so:

// merged-prettier-plugin.js

const tailwind = require('prettier-plugin-tailwindcss')
const organizeImports = require('prettier-plugin-organize-imports')

const combinedFormatter = {
  ...tailwind,
  parsers: {
    ...tailwind.parsers,
    ...Object.keys(organizeImports.parsers).reduce((acc, key) => {
      acc[key] = {
        ...tailwind.parsers[key],
        preprocess(code, options) {
          return organizeImports.parsers[key].preprocess(code, options)
        },
      }
      return acc
    }, {}),
  },
}

module.exports = combinedFormatter
// .prettierrc.js

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

This works for now because, from what I can tell, prettier-plugin-tailwindcss doesn’t set a preprocessor, and prettier-plugin-organize-imports does all of its work in the preprocessor.

Looking forward to whatever eventual fix removes the need for the patch!

Subscribing to this. Working with Craft CMS, it’s disappointing to see this is incompatible with prettier-plugin-twig-melody.

Hello, Erika from the Astro team here. Any idea when the current main will be released?

We contributed Astro support 2 months ago now and our users understandably keep asking us to support this. I know there was some needed changes after our PR, but it seems like those changes were merged in a month ago.

If there’s anything we can do to help get this released - please let us know and we’ll gladly contribute!

Are all these incompatibilities meant to be fixed at some point, or is this issues point to inform us that we can’t use a combination of said plugins without odd workarounds?

I think the premise of your question is a bit misplaced. My experience with open-source software, unless funded by big sponsors, is that contributors submit patches mostly to solve their own problems. So either you have to get your hands dirty and submit a PR to solve this, or cross your fingers and hope that someone else has enough motivation to sacrifice their free time one day and do the work for you.

Sup everyone! 👋

Just another update on the Tailwind CSS Prettier plugin. We’ve now added support for a bunch of other Prettier plugins and have released a new beta version for your testing pleasure.

Here’s a complete list of all the plugins we added support for in this release:

  • @prettier/plugin-php
  • @prettier/plugin-pug
  • prettier-plugin-css-order
  • prettier-plugin-import-sort
  • prettier-plugin-jsdoc
  • prettier-plugin-organize-attributes
  • prettier-plugin-style-order
  • prettier-plugin-twig-melody

Installing the beta

As previously mentioned, we need to do some shenanigans to get these plugins all working (I’m looking at you @prettier/plugin-php), so we’d really appreciate your help kicking the tires on this new version for us.

To install this latest beta, add it using npm:

npm install prettier-plugin-tailwindcss@beta

As mentioned in my previous comment, the one gotcha with this approach is that Prettier plugin autoloading is unreliable, because our plugin must come last in the list of plugins. For this reason, you’ll need to explicitly disable the pluginSearchDirs option, and define each of your Prettier plugins in the plugins array:

// .prettierrc
{
  // ..
  "plugins": [
    "@prettier/plugin-pug",
    "prettier-plugin-organize-attributes",
    "prettier-plugin-tailwindcss" // MUST come last
  ],
  "pluginSearchDirs": false
}

Other plugins

I think this covers all the Prettier plugins mentioned in this issue other than @shufo/prettier-plugin-blade, which unfortunately is more complicated since that plugin forks out to a different process and doesn’t provide an AST — just a string. So we’d have to parse the whole Blade file ourselves to be able to sort classes within it, which is a much bigger undertaking.

Thank you @reinink 👏

For anyone struggling, this works with pnpm:

plugins: [
    require.resolve('@trivago/prettier-plugin-sort-imports'),
    require('prettier-plugin-tailwindcss'),
],

Reading the discussion here, according to Prettier’s team, re-ordering classes should not be done through Prettier but through ESLint, which is why they do not plan to solve it 😅 Should the effort be redirected to an ESLint plugin? (official support for the existing ones?)

how about this issue

For those that are using eslint (with autofix) in conjunction with prettier, eslint-plugin-tailwindcss might be a viable alternative.

Thanks for updating this. Sad it’s still incompatible with Twig 😦

@Princesseuh I think it’s still blocked by what @thecrypticace outlined here: https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/87#issuecomment-1218432784

We’re really busy trying to get Tailwind CSS v3.2 out the door this week and then out for a team retreat the following week, but we can look at this again the first week of November. One idea we might need to explore is multiple plugins, like a prettier-plugin-tailwindcss-astro plugin and a separate pretter-plugin-tailwindcss-svelte plugin or similar since it seems to be proving challenging to build something that works everywhere 😕

Might be a bit of an edge case. But I am using Laravel and subsequently Blade template files.

So that prettier runs on these files I am using @shufo/prettier-plugin-blade. But as this issue suggests, Tailwind classes are not sorted when run with this plugin.

Hey @blooddrunk, this workaround worked for me:

const tailwindPlugin = require('prettier-plugin-tailwindcss');
const sortImportsPlugin = require('@ianvs/prettier-plugin-sort-imports');

module.exports = {
  parsers: {
    typescript: {
      ...tailwindPlugin.parsers.typescript,
      preprocess: sortImportsPlugin.parsers.typescript.preprocess,
    },
  },
  options: {
    ...sortImportsPlugin.options,
  },
};

Related to this answer.

Are all these incompatibilities meant to be fixed at some point, or is this issues point to inform us that we can’t use a combination of said plugins without odd workarounds?

Looking forward for this to be compatible with @ianvs/prettier-plugin-sort-imports

Seems this one might be incompatible as well https://github.com/withastro/prettier-plugin-astro

Agreed, having this issue as well.

It’s not a pretty solution, …

I see what you did there.

Thank you @reinink 👏

For anyone struggling, this works with pnpm:

plugins: [
    require.resolve('@trivago/prettier-plugin-sort-imports'),
    require('prettier-plugin-tailwindcss'),
],

Beautiful thanks! This worked for me (Next 13, pnpm)

@TrevorLeeman are you using pnpm? I think I noticed the same thing when I moved to pnpm from yarn (v1). I’ll try and get back to this thread with a result.

EDIT: confirmed. Reverting to Yarn solved the issue 😃

@kagurazaka-0 Thanks for sharing. This looks like a promising solution, but I was personally not able to get it working. Continuously got this error in the Prettier output after making the change to the prettier.config.js:

Error formatting document. TypeError: Cannot read properties of undefined (reading 'map') at Object.getExperimentalParserPlugins

When only using plugins: [require('prettier-plugin-tailwindcss')] or plugins: [require('@trivago/prettier-plugin-sort-imports')], individually, Prettier works as expected.

@blooddrunk @bryanbarrios Just a heads up that we’ve also added support for @ianvs/prettier-plugin-sort-imports: https://github.com/tailwindlabs/prettier-plugin-tailwindcss/releases/tag/v0.2.3

@mreduar Hey, yes, you still to disable the pluginSearchDirs and list all your plugins in the plugins array, putting Tailwind CSS last (as per the readme).

If it’s not working there is probably something else wrong. Feel free to create a minimal reproduction and we can have a closer look 👍

Hiya, did anyone found a workaround when using pnpm ?

I figured out what I was doing wrong and the reason I couldn’t get it to work for SvelteKit before was because I was trying to include the plugin inside .prettierrc which for some reason breaks it, so don’t include it and it should pick it up.

👎️ .prettierrc

{
  "plugins": ["prettier-plugin-tailwindcss"]
}

Here are the steps for SvelteKit users:

  1. pnpm i -D prettier-plugin-tailwindcss
  2. pnpm remove prettier-plugin-svelte

You can keep using the svelte.svelte-vscode formatter.

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

You can look at the updated repo if you need an example.

I for one can say that I can install and integrate: @tailwindcss/forms and it has 0 affect on this Prettier plugin.

I don’t particular care for the defaults put forth in the forms extension, so I don’t usually use it. Just tried it out when I saw these issues.

As to all of the other plugins, I don’t personally use all of those, but other ones such as standard prettier, or prettier for Jest I do use and never had any issue.

If you want a workaround, you could use the prettier --config flag and have two different configs (using the sharing configurations patter for consistent formatting).

This solution won’t work with your IDE on saving, but it could work with a lint-stage solution.

prettier --config ./.prettierrc.tailwind.js --write .
prettier --config ./.prettierrc.other.js --write .

It’s not a pretty solution, but I think it’s possible for those that strongly want multiple plugin support.

I, personally, have decided to use the tailwind prettier plugin on its own for now to avoid adding this much complexity to my projects.

what’s progress of this issue, i run into this issue, it will break pluginprettier-plugin-organize-imports,

@rwwagner90 It’s not that this plugin is incompatible with prettier-plugin-astro, but this plugin only works with a few extensions (such as vue, html, etc).

@itz4rv This issue is 20 months old. The instructions have changed such that we no longer have to bundle Svelte and you include it in your plugins list like you’d do that with any other.

This is documented in the readme: https://github.com/tailwindlabs/prettier-plugin-tailwindcss#compatibility-with-other-prettier-plugins

The issue was a problem with my VSCode, all worked after restart

Seems like it’s not working when used with “prettier-plugin-organize-attributes”

It is still not working for me: .prettierrc.cjs

module.exports = {
  trailingComma: "all",
  tabWidth: 2,
  semi: true,
  singleQuote: false,

  plugins: [
    "prettier-plugin-packagejson",
    "prettier-plugin-jsdoc",
    "@trivago/prettier-plugin-sort-imports",
    // Must be loaded last
    "prettier-plugin-tailwindcss",
  ],

  // prettier-plugin-tailwindcss
  tailwindAttributes: ["classProp"],

  // @trivago/prettier-plugin-sort-imports
  // https://github.com/trivago/prettier-plugin-sort-imports#usage
  importOrder: ["^#styles(.*)$", "<THIRD_PARTY_MODULES>", "^#(.*)$", "^[./]"],
  importOrderSeparation: true,
  importOrderSortSpecifiers: true,
  importOrderGroupNamespaceSpecifiers: true,
};

package.json

"devDependencies": {
    "@tailwindcss/typography": "^0.5.10",
    "@trivago/prettier-plugin-sort-imports": "^4.3.0",
    "prettier": "3.1.0",
    "prettier-plugin-jsdoc": "^1.1.1",
    "prettier-plugin-packagejson": "^2.4.6",
    "prettier-plugin-tailwindcss": "^0.5.7",
    "tailwindcss": "^3.3.5",
    "typescript": "5.2.2",
    "vite": "^5.0.0",
  },

Based on : https://github.com/tailwindlabs/prettier-plugin-tailwindcss#compatibility-with-other-prettier-plugins

🤔

@ramblehead Hey! So we actually already have support for prettier-plugin-jsdoc, see here: https://github.com/tailwindlabs/prettier-plugin-tailwindcss#compatibility-with-other-prettier-plugins

@sameeranand1 Done: #102 🤙

This has been released as 0.2.0-beta.3.

@reinink Can you add support for @shopify/prettier-plugin-liquid? This is for Shopify themes. https://github.com/tailwindlabs/prettier-plugin-tailwindcss/issues/98

@mattcroat I really appreciate this, and I did try but IDE kept showing Saving '+page.svelte': Running 'Svelte for VS Code' Formatter toast message while I was trying to save. If I try to navigate to a different file the toast message disappears and saves the file.

The formatting was successful by the end of the wait and consequent save did not have this problem. Just throwing this here to see if others faced this issue. I faced this issue both with my personal repo and also the repo shared by @mattcroat

cc. @reinink

Would be very nice, if we had support for this one: https://github.com/prettier/plugin-pug The markup used in pug can look like this: h1(class="text-center font-serif"), which is in terms of classes is the same as HTML. If anyone has a possible solution, I’d be very grateful. Thanks!

I don’t know if it is also related to this, but I can’t have prettier-plugin-tailwindcss working alongside @tailwindcss/forms. It says it doesn’t find it.

I found a workaround on this one

Create a tailwind.shared.config.js contains all the things without @tailwindcss/forms

/** @type {import("tailwindcss").Config}  */
module.exports = {
  darkMode: 'class',
  content: [
    './src/pages/**/*.{js,ts,jsx,tsx}',
    './src/components/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {},
}

Then in normal tailwind.config.js add the plugins back.

const config = require('./tailwind.shared.config.js')

/** @type {import("tailwindcss").Config}  */
module.exports = {
  ...config,
  plugins: [
    require('@tailwindcss/forms'),
  ],
}

in .prettierrc.js use the config file without @tailwindcss/forms

module.exports = {
  // other configs
  tailwindConfig: './tailwind.shared.config.js',
}

https://github.com/tailwindlabs/prettier-plugin-tailwindcss/issues/31#issuecomment-1195411734 @kagurazaka-0 Thank you! I try it and it works well! Now I wait until I would be able to remove this workaround.

@manavm1990 This issue is specifically in regards to those other plugins, not for the standard prettier plugin which this tailwind plugin was built for and can be used in tandem with forms 👍

Any workarounds @guilhermetod ?

If you want a workaround, you could use the prettier --config flag and have two different configs (using the sharing configurations patter for consistent formatting).

This solution won’t work with your IDE on saving, but it could work with a lint-stage solution.

prettier --config ./.prettierrc.tailwind.js --write .
prettier --config ./.prettierrc.other.js --write .

It’s not a pretty solution, but I think it’s possible for those that strongly want multiple plugin support.

I, personally, have decided to use the tailwind prettier plugin on its own for now to avoid adding this much complexity to my projects.

Thanks for the idea, I made a lintstaged script to run eslint (with prettier tailwindcss) + prettier (with prettier sort imports), here is an example

@nunocasteleira this issue is related to prettier plugins conflicting with each other.

If your system can’t find @tailwindcss/forms try reinstalling it with npm install @tailwindcss/forms.

If you continue to have problems open an issue on the forms repo.