/ astro-integrations / How to Use Tailwind CSS with Astro: Complete Guide
astro-integrations 8 min read

How to Use Tailwind CSS with Astro: Complete Guide

Step-by-step guide to integrating Tailwind CSS with your Astro website. Installation, configuration, and best practices.

How to Use Tailwind CSS with Astro: Complete Guide

Tailwind CSS and Astro are a natural pair. Astro ships zero JavaScript by default, and Tailwind only emits the classes you actually use, so you end up with a tiny CSS bundle and fast pages. As of Tailwind v4, the recommended way to wire it into Astro is the official Vite plugin (@tailwindcss/vite), which replaces the older @astrojs/tailwind integration. This guide uses Tailwind CSS v4.3 and Astro v6, both current as of late May 2026.

Heads Up: The Setup Changed in Tailwind v4

If you have read an older tutorial, you may have seen npm install @astrojs/tailwind and a tailwind.config.mjs file. That approach is now legacy. Tailwind v4 moved to a Vite-first architecture and a CSS-first configuration model. The current path is:

  • Install tailwindcss and @tailwindcss/vite.
  • Register the plugin under vite.plugins in astro.config.mjs.
  • Add a single @import "tailwindcss"; line to a CSS file and import that file once.

There is no tailwind.config.js, no postcss.config.js, and no separate autoprefixer step by default. The Astro docs note that @astrojs/tailwind plus tailwindcss@3 is only kept around for projects that still need Tailwind 3. For anything new, use the Vite plugin.

Prerequisites

  • Node.js 22.12.0 or newer (Astro v6 dropped Node 18 and 20; its engines field requires node >=22.12.0)
  • An Astro project (npm create astro@latest)

Installation

The easiest way to add Tailwind to Astro (Astro 5.2.0 and later) is the official add command:

npx astro add tailwind

This installs @tailwindcss/vite and tailwindcss, registers the Vite plugin in your Astro config, and creates a src/styles/global.css file with the Tailwind import already in place. One command, done.

If you prefer to do it manually, install the two packages:

npm install tailwindcss @tailwindcss/vite

As of this writing both tailwindcss and @tailwindcss/vite are at v4.3.0.

Configuration

In Tailwind v4 the integration is a Vite plugin, so it goes under the vite key in your Astro config, not the top-level integrations array:

// astro.config.mjs
// @ts-check
import { defineConfig } from "astro/config";
import tailwindcss from "@tailwindcss/vite";

export default defineConfig({
  vite: {
    plugins: [tailwindcss()],
  },
});

Then create a CSS file (the astro add tailwind command makes this for you) with a single import line:

/* src/styles/global.css */
@import "tailwindcss";

Finally, import that CSS file once, typically in your base layout so every page picks it up:

---
// src/layouts/BaseLayout.astro
import "../styles/global.css";
---

<slot />

That is the whole setup. There is no content array to maintain. Tailwind v4 automatically detects your template files, so you no longer hand-list globs like ./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}.

Basic Usage

Start using Tailwind classes directly in your Astro components:

---
// src/pages/index.astro
import BaseLayout from "../layouts/BaseLayout.astro";
---

<BaseLayout title="Home">
  <main class="max-w-4xl mx-auto px-4 py-12">
    <h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-4">
      Welcome to My Site
    </h1>
    <p class="text-lg text-gray-600 dark:text-gray-300 leading-relaxed">
      Built with Astro and styled with Tailwind CSS.
    </p>
    <a
      href="/blog"
      class="inline-block mt-6 px-6 py-3 bg-blue-600 text-white rounded-lg
             hover:bg-blue-700 transition-colors"
    >
      Read the Blog
    </a>
  </main>
</BaseLayout>

Adding Custom Styles and Plugins

Tailwind v4 is CSS-first. Instead of editing a JavaScript config, you define your design tokens with the @theme directive right in your CSS file. Custom colors and fonts become utilities and CSS variables automatically:

/* src/styles/global.css */
@import "tailwindcss";

@theme {
  --color-brand-50: #eff6ff;
  --color-brand-500: #3b82f6;
  --color-brand-900: #1e3a5f;

  --font-sans: "Inter", system-ui, sans-serif;
}

That gives you utilities like bg-brand-500, text-brand-900, and font-sans, plus matching CSS variables such as var(--color-brand-500).

Plugins are also loaded from CSS now, with the @plugin directive, rather than a plugins: [require(...)] array:

/* src/styles/global.css */
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms";

Install the plugins:

npm install @tailwindcss/typography @tailwindcss/forms

The typography plugin is especially useful for blog content. Wrap your article body in a prose class and it handles all the typography for you:

<article class="prose prose-lg dark:prose-invert max-w-none">
  <slot />
</article>

Dark Mode

By default Tailwind v4 ties the dark: variant to the user's operating-system preference via prefers-color-scheme, so it works with no configuration at all. If you want a manual toggle driven by a dark class on the <html> element, override the variant in your CSS with @custom-variant. The v3 darkMode: "class" config key no longer exists:

/* src/styles/global.css */
@import "tailwindcss";
@custom-variant dark (&:where(.dark, .dark *));

Then toggle the dark class on <html> from JavaScript and use dark: variants in your markup as usual:

<div class="bg-white dark:bg-gray-900">
  <h1 class="text-gray-900 dark:text-white">Hello</h1>
</div>

Production Tips

  1. Use the typography plugin for prose content. It styles rendered Markdown and HTML beautifully without manual class wrangling. One class, professional typography.

  2. You do not need to configure JIT or purging. Tailwind v4 is built on a new high-performance engine that scans your templates automatically and only emits the classes you use. There is no content array to maintain and nothing to purge by hand.

  3. Create component classes with @apply. For repeated patterns, use @apply in your global CSS file rather than repeating long class strings everywhere:

/* src/styles/global.css */
@layer components {
  .btn-primary {
    @apply px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors;
  }
}
  1. Keep your theme organized in CSS. As your design system grows, group related tokens under @theme and lean on the generated CSS variables. You can share a theme across projects by importing a common CSS file.

  2. Use the Tailwind VS Code extension. It gives you autocomplete for class names, inline previews of colors, and lint warnings for conflicting utilities. The v4 extension understands the new CSS-first directives.

A Note on Rendering

The Tailwind setup is identical whether your Astro pages are statically generated or rendered on demand. Astro is static by default, and the old output: 'hybrid' option was removed in Astro 5, so you no longer set output for mixed sites. Mark individual routes with export const prerender = false for on-demand rendering, and add a server adapter (for example @astrojs/node) if you need server-rendered pages. Tailwind itself runs entirely at build time through Vite either way.

Alternatives to Consider

  • UnoCSS if you want a faster, more customizable atomic CSS engine that is compatible with Tailwind's class syntax. It also has an official Astro integration.
  • Open Props if you prefer CSS custom properties over utility classes. It provides design tokens you can use with regular CSS.
  • Vanilla Extract if you want type-safe CSS in TypeScript with zero runtime cost. Good for larger, more structured projects.

Common Errors and Fixes

  • You followed an old guide and ran npm install @astrojs/tailwind. That integration targets Tailwind 3 and is now legacy. For a new project remove it, install tailwindcss and @tailwindcss/vite, and switch the config from the integrations array to vite.plugins.
  • You put tailwindcss() in the wrong place. In v4 the plugin is a Vite plugin. Putting it in Astro's top-level integrations array will not apply Tailwind. It must live under vite: { plugins: [tailwindcss()] }.
  • No styles appear at all. The most common cause is forgetting to import your CSS file. The @import "tailwindcss"; file has to be imported once from a page or layout (for example import "../styles/global.css" in your base layout). If you ran astro add tailwind, confirm the generated src/styles/global.css is actually imported.
  • You are looking for tailwind.config.js and cannot find it. Tailwind v4 is CSS-first and does not create one. Configure your theme with @theme and load plugins with @plugin directly in your CSS. A JS or TS config is optional and only needed for advanced cases, loaded with @config.
  • darkMode: "class" does nothing. That config key was removed in v4. Use @custom-variant dark (&:where(.dark, .dark *)); in your CSS for class-based dark mode, or rely on the default prefers-color-scheme behavior.
  • @plugin "@tailwindcss/typography" errors out. Make sure the plugin package is installed (npm install @tailwindcss/typography). The @plugin directive loads an installed package by name; it does not install it for you.

Official Docs and Examples

Wrapping Up

Tailwind CSS is the most popular way to style an Astro site for good reason. With Tailwind v4 the official Vite plugin makes setup trivial, the CSS-first config keeps your theme in one place, and the build output is tiny because only the classes you use are emitted. If you are starting a new Astro project, run astro add tailwind and start building.

Sources

Checked on 2026-05-29.