astro-integracion-tailwind

Using Tailwind CSS in Astro

  • 5 min

We’ve seen how Astro natively handles styles via scoped CSS and standard modules. For many (myself included), this is the ideal way to work due to its semantics and cleanliness.

However, one of the most popular libraries today is Tailwind CSS, a “utility-first” framework that proposes a different paradigm. Applying styles via predefined classes directly in the HTML.

Whether you like Tailwind or not (it has its pros and cons), the reality is that Astro and Tailwind make a good pair because:

  • Astro’s component-based architecture mitigates Tailwind’s main drawback (messy, repetitive HTML).
  • While Tailwind solves design system management without leaving the HTML.

So, let’s see how to configure our Astro project to use Tailwind, and it also serves as an excuse to introduce Astro integrations.

Astro Integrations

Before installing Tailwind, it’s a good time to introduce one of Astro’s star features: Integrations.

In other systems, configuring tools like Tailwind, React, Svelte, or sitemaps usually involves touching complex configuration files (webpack.config.js, postcss.config.js, etc.), manually installing dependencies, and praying that the versions are compatible.

Astro solves this with the CLI command astro add. This command not only installs dependencies but also automatically modifies your configuration files to set everything up and ready to use.

Automatic Installation

Open your terminal at the project root and run:

npx astro add tailwind

When you run this, Houston (the CLI) will take control and ask for confirmation to perform three actions:

Install dependencies: It will download tailwindcss and @astrojs/tailwind.

Create configuration: It will generate the tailwind.config.mjs file in the root.

Update Astro configuration: It will modify astro.config.mjs to inject the integration.

We say Yes to everything, and that’s it. You now have Tailwind working. Without having to do anything else. Astro automatically injects Tailwind’s base styles into all your pages.

What changed in my project?

If we look at the astro.config.mjs file, we’ll see this:

import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';

export default defineConfig({
  // The integration has been added here
  integrations: [tailwind()],
});
Copied!

This line lets Astro know it must process Tailwind classes and generate the final optimized CSS.

Tailwind Configuration

The command created a tailwind.config.mjs file. This is where we customize our design system (colors, fonts, breakpoints).

/** @type {import('tailwindcss').Config} */
export default {
  content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
  theme: {
    extend: {
      colors: {
        'brand-primary': '#4F46E5', // Our corporate color
      }
    },
  },
  plugins: [],
}
Copied!

Tailwind works via JIT (Just-In-Time). It scans your files for classes and generates only the CSS you are using.

Look at the content line. If you use a new file with a different extension, make sure to add it here or Tailwind will ignore its classes.

Using Tailwind in Astro Components

Now we can use utility classes directly in our components. Remember that in Astro we use the standard class attribute, not className.

---
// src/components/Card.astro
const { title } = Astro.props;
---

<div class="bg-white rounded-xl shadow-md overflow-hidden p-6 hover:shadow-lg transition-shadow">
  <h2 class="text-2xl font-bold text-gray-800 mb-2">{title}</h2>
  <p class="text-gray-600">
    This component is styled 100% with Tailwind.
  </p>
  
  <button class="mt-4 bg-brand-primary text-white px-4 py-2 rounded">
    Read more
  </button>
</div>
Copied!

The @apply Directive

Sometimes, the list of classes becomes too long and hard to read, or you simply want to reuse a set of styles without creating a new component.

We can use Tailwind’s @apply directive inside the <style> tag of our Astro component.

<button class="btn-primary">
  Click me
</button>

<style>
  /* We can mix normal CSS with Tailwind.
    Remember: These styles are still SCOPED (local) by default.
  */
  .btn-primary {
    @apply px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 transition-colors;
    
    /* We can add standard CSS rules that Tailwind doesn't have */
    text-transform: uppercase;
  }
</style>
Copied!

Global Styles and Fonts

The Astro integration automatically injects Tailwind’s basic directives (@tailwind base, etc.). But what if we want to add a custom font or global styles for the body?

Create a CSS file, for example src/styles/global.css:

/* src/styles/global.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
  h1 {
    @apply text-4xl font-bold mb-4;
  }
  h2 {
    @apply text-2xl font-semibold mb-3;
  }
}
Copied!

And then import it into our main Layout:

---
// src/layouts/Layout.astro
import '../styles/global.css';
---
Copied!