The short version

Install Prettier with prettier-plugin-astro and prettier-plugin-tailwindcss, list both plugins in .prettierrc with the Tailwind plugin last, and point tailwindStylesheet at your CSS entry file on Tailwind 4. Run npx prettier . --write locally and --check in CI. At the time of writing, prettier-plugin-tailwindcss 0.8.1 does not sort classes in .astro files with prettier-plugin-astro 1.x, and Prettier shows no error. The fix is merged but not yet released. Other causes of unsorted classes are the plugin order, a missing tailwindStylesheet option, and an editor that runs a different Prettier than your project.

Formatting is a solved problem if you configure it once. Prettier is a code formatter: it handles indentation, quotes, and line breaks across the codebase. With two plugins, prettier-plugin-astro and prettier-plugin-tailwindcss, it can also format .astro files and sort Tailwind classes. There is one catch. At the time of writing, the latest stable releases of the two plugins leave Tailwind classes in .astro files unsorted, and Prettier shows no error. This guide gives you the minimum setup for an Astro project with Tailwind CSS 4 and Prettier 3. It also covers what to do until a stable release fixes the problem, and the checks I run when the Tailwind plugin stops working.

The setup needs two plugins and one configuration file. Two changes shape it: Prettier 3 stopped discovering plugins automatically, and Tailwind 4 moved its configuration from a JavaScript file into CSS. Both affect the steps below. You need Node.js (the current LTS version) and, if you work in VS Code, the Astro, Prettier, and Tailwind CSS IntelliSense extensions.

Step 01

Create an Astro project with Tailwind CSS

If you do not have a project yet, create one and add Tailwind:

bash
npm create astro@latest
cd my-project
npx astro add tailwind

Astro asks a few questions first; a minimal template with strict TypeScript is a sensible default. The astro add tailwind command adds the Tailwind Vite plugin to astro.config.mjs, which is the recommended integration for Tailwind 4.

Create src/styles/global.css with @import "tailwindcss"; if the command has not already created it, and import that stylesheet in your shared layout frontmatter with import '../styles/global.css' (adjust the relative path). The Vite plugin alone does not apply styles to a page.

Step 02

Install Prettier, prettier-plugin-astro and prettier-plugin-tailwindcss

From the project folder, install Prettier and both plugins as exact dev dependencies:

bash
npm install --save-dev --save-exact prettier prettier-plugin-astro prettier-plugin-tailwindcss

Pinning the exact version matters more than it looks. Prettier changes its output between releases, so a teammate or a CI runner with a slightly newer version can reformat files you never touched. prettier-plugin-astro is the official Astro plugin; prettier-plugin-tailwindcss is maintained by Tailwind Labs and requires Prettier 3.

At the time of writing (October 2026), the command above installs prettier-plugin-astro 1.x and prettier-plugin-tailwindcss 0.8.1. With that combination, classes in .astro files are not sorted, and Prettier shows no error. Classes in other file types still sort. Tailwind Labs has merged a fix in pull request #473, but no stable release includes it yet.

Until a release after 0.8.1 ships, you can accept unsorted classes in .astro files. If you want them sorted now, there is an optional extra step: install the pre-release build that Tailwind Labs publishes under the insiders tag. It already includes the fix:

bash
npm install --save-dev --save-exact prettier-plugin-tailwindcss@insiders

That build is a pre-release, not a stable version. Once the next stable release is out, switch to it with npm install --save-dev --save-exact prettier-plugin-tailwindcss@latest.

Whichever you choose, keep prettier-plugin-astro on 1.x. A new project from npm create astro@latest runs Astro 7. Do not downgrade the plugin to 0.14.x there. That version was built for Astro’s older whitespace handling. The prettier-plugin-astro README notes that Astro’s default compressHTML mode has been jsx since Astro 7.0.0. That mode drops whitespace that contains a line break. Version 0.14.x can put a line break between a word and an inline element such as <code>, and the rendered page then glues the word to the text inside that element.

Step 03

Configure .prettierrc for Astro and Tailwind

Create a .prettierrc file in the root of your project:

json
{
  "useTabs": true,
  "singleQuote": true,
  "trailingComma": "none",
  "semi": false,
  "printWidth": 100,
  "plugins": ["prettier-plugin-astro", "prettier-plugin-tailwindcss"],
  "overrides": [{ "files": "*.astro", "options": { "parser": "astro" } }],
  "tailwindStylesheet": "./src/styles/global.css"
}

The first five options are my own preferences, so change them freely. The last three lines are the part that has to be right. plugins loads both plugins, because Prettier 3 no longer finds them on its own. The overrides block sets the Astro parser for .astro files, which the Astro editor setup docs recommend for reliable results across package managers. tailwindStylesheet tells the Tailwind plugin where your CSS entry file lives.

Add a .prettierignore for files Prettier should leave alone:

dist/
node_modules/
vercel.json

Step 04

Run Prettier from the command line and in CI

Format the whole project once:

bash
npx prettier . --write

That rewrites every file Prettier supports, so commit your work before the first run and review the diff. In CI, use the check mode instead:

bash
npx prettier . --check

--check changes nothing. It lists the files that are not formatted and exits with code 1, which fails the pipeline. To format on save in VS Code, turn on Editor: Format On Save and pick Prettier as the default formatter.

What prettier-plugin-tailwindcss does

The plugin sorts the classes in your class attributes, framework equivalents such as className, and @apply directives. It uses the same order Tailwind uses in the generated CSS. Before formatting, a button might look like this:

html
<button class="text-white px-4 sm:px-8 py-2 sm:py-3 bg-sky-700 hover:bg-sky-800">Save</button>

After npx prettier . --write, it looks like this:

html
<button class="bg-sky-700 px-4 py-2 text-white hover:bg-sky-800 sm:px-8 sm:py-3">Save</button>

The order follows a few rules from Tailwind’s announcement post. Layout classes come before decorative ones, and modifiers such as hover: follow the plain utilities. Responsive variants go last, from small to large. Custom classes that Tailwind does not know, such as a class for a third-party widget, move to the front so you spot them right away. You cannot change that order. In practice you stop noticing it within a week, and you never discuss class order in a code review again.

Classes inside function calls such as clsx() or cva() are not sorted by default. List those functions in the tailwindFunctions option if you want them sorted too.

Tailwind 4 vs Tailwind 3: tailwindStylesheet or tailwindConfig

Tailwind 4 keeps its configuration in CSS: your theme, custom utilities, and plugins live in the stylesheet that starts with @import "tailwindcss";. The plugin’s README states that on Tailwind 4 you must point the tailwindStylesheet option at that entry file. Without it, the plugin does not know your custom theme tokens. It treats those classes as unknown and moves them to the front.

Tailwind 3 projects use tailwindConfig instead. Without that option, the plugin searches for tailwind.config.js itself. It starts in the folder of the file being formatted and works its way up through the parent folders. If it cannot find your config that way, set the path explicitly:

json
{
  "tailwindConfig": "./styles/tailwind.config.js"
}

For both options, a path you set is resolved relative to the Prettier configuration file, not to the file being formatted. That detail causes a lot of confusion in monorepos, where the .prettierrc sits a few folders above the app.

Prettier Tailwind plugin not working? Check these first

When classes stop sorting or .astro files stay untouched, I go through this list in order. Each point is based on the official docs and changelogs of Prettier and both plugins. The version clash and the stylesheet behavior were also reproduced in a test project in October 2026.

  1. The plugin versions clash in .astro files. With prettier-plugin-astro 1.x and prettier-plugin-tailwindcss 0.8.1, classes in .astro files stay unsorted. Prettier shows no error, and prettier --check exits with code 0, so a CI check does not catch it. The same config still sorts .html files, which makes the problem easy to miss. Run npm ls prettier-plugin-astro prettier-plugin-tailwindcss to see which versions you have. At the time of writing (October 2026), the Tailwind plugin changelog lists the fix (#473) under Unreleased. Until a release after 0.8.1 includes it, accept unsorted classes in .astro files or use the insiders pre-release from the install step, then move to the next stable release. On Astro 7, do not downgrade prettier-plugin-astro to 0.14.x, because it can glue words together on the rendered page. On Astro 6 or older, prettier-plugin-astro 0.14.1 with prettier-plugin-tailwindcss 0.8.1 does sort .astro classes.
  2. The plugin is not in plugins. Prettier 3 does not discover plugins automatically. If prettier-plugin-tailwindcss is installed but not listed, nothing happens and Prettier shows no error.
  3. The Tailwind plugin is not last. The README is explicit: prettier-plugin-tailwindcss must be loaded last. Put prettier-plugin-astro, prettier-plugin-svelte, and import-sorting plugins before it.
  4. tailwindStylesheet is missing or points to the wrong file. On Tailwind 4, the path must lead to the CSS file with @import "tailwindcss";, relative to the .prettierrc. Without the option, Prettier still runs, but the plugin does not know your custom theme. Classes from that theme, such as bg-brand from an @theme color, then count as unknown and move to the front. Prettier shows no error. A typo in the path fails loudly instead: Prettier stops with an ENOENT error that names the missing file and exits with code 2.
  5. Your config uses require() on an older Node version. The plugin is ESM-only. On Node versions before 20.19, a prettier.config.cjs that loads it with require() can fail. Use .prettierrc JSON or an ESM prettier.config.mjs instead, or update Node. The current plugin release lists Node 20.19 or later as its minimum.
  6. The editor runs a different Prettier. If the command line sorts correctly but your editor does not, the editor is probably using its own bundled Prettier or another formatter. Install Prettier locally, set Prettier as the default formatter, and restart the editor after changing plugins.
  7. VS Code ignores .astro files. When you format with the Prettier extension instead of the Astro extension, the prettier-plugin-astro README asks for two settings: "prettier.documentSelectors": ["**/*.astro"] and "editor.defaultFormatter": "esbenp.prettier-vscode" under "[astro]".
  8. The cache is stale. With --cache, Prettier does not use plugin versions as cache keys. Delete the cache in node_modules/.cache/prettier after updating a plugin.

ESLint next to Prettier in Astro

Prettier formats, ESLint finds problems such as unused variables or risky patterns. They work fine together as long as ESLint stops enforcing style rules. The Astro docs point to the community plugin eslint-plugin-astro; add eslint-config-prettier to switch off every ESLint rule that conflicts with Prettier:

bash
npm install --save-dev eslint eslint-plugin-astro eslint-config-prettier
js
// eslint.config.mjs
import eslintPluginAstro from 'eslint-plugin-astro'
import eslintConfigPrettier from 'eslint-config-prettier/flat'

export default [...eslintPluginAstro.configs.recommended, eslintConfigPrettier]

Keep eslintConfigPrettier last so it overrides the configs before it. ESLint only targets .js files by default, so run it with a glob such as npx eslint "src/**/*.{js,astro}". In VS Code, add "astro" to the eslint.validate setting. If you write TypeScript in Astro components, also install typescript-eslint, as described in the eslint-plugin-astro user guide.

Prefer a single tool? Biome is an all-in-one linter and formatter, but its .astro support is still marked experimental in the Astro docs. For now, Prettier remains the formatter I use on Astro projects.

Wrapping up

That is the complete setup. List both plugins with Tailwind last, add the Astro parser override, and point tailwindStylesheet at your CSS entry file. Keep an eye on the next prettier-plugin-tailwindcss release, which should bring the fix for class sorting in .astro files. Run the same pinned Prettier version in the editor and in CI. Your code then follows the same format on every machine, and code reviews can focus on the work rather than whitespace.

The full Astro setup guide covers the wider starter configuration, including Svelte, Vercel and TypeScript. If you would rather hand over the build, you can hire an Astro developer to handle the project setup and implementation.