Upgrading TailwindCSS to v4 in an Astro Blog

Introduction

A while ago, TailwindCSS v4 was released, and I updated my portfolio site accordingly.

I’ve been wanting to update this Astro-based blog as well, but I was waiting for the @astrojs/tailwind plugin to support v4. Recently, a pull request adding v4 support was merged. Upon reviewing the changes, I realized that TailwindCSS v4 now provides a Vite plugin, making @astrojs/tailwind unnecessary—there was no need to wait for the plugin update.

So, I immediately upgraded this blog to TailwindCSS v4 and documented the process.

Upgrade Steps

Setting Up Dependencies

First, install the new @tailwindcss/vite plugin:

npm install @tailwindcss/vite

Then, remove the old @astrojs/tailwind plugin. Although version 6 has been released, it only exists to ease migration for existing projects and will not receive new features.

npm rm @astrojs/tailwind

Updating astro.config.mjs

Next, update astro.config.mjs to replace @astrojs/tailwind with @tailwindcss/vite. Note that @tailwindcss/vite should be specified under vite.plugins, not integrations.

import { defineConfig } from "astro/config";
// import tailwind from "@astrojs/tailwind"; // Remove
import tailwindcss from "@tailwindcss/vite"; // Add

export default defineConfig({
  integrations: [
    // tailwind(), // Remove
  ],
  vite: {
    plugins: [
      tailwindcss(), // Add
    ],
  },
})

Updating tailwind.config.mjs and Main CSS

With TailwindCSS v4, tailwind.config.mjs is no longer required—you can now configure Tailwind directly in a CSS file. Create a file src/styles/app.css (the name is arbitrary) and migrate the settings from tailwind.config.mjs.

/* Required: Import TailwindCSS */
@import "tailwindcss";

/* Optional: If using @tailwindcss/typography, import it */
@plugin "@tailwindcss/typography";

/* Optional: If migration is troublesome, you can still import the old config file */
@config "../../tailwind.config.mjs";

/* Move settings from tailwind.config.mjs here */

Finally, import this file in your project. Since my BaseLayout.astro is used across all pages, I included it there:

import "../styles/app.css";

Handling @apply

When running the development server, you might encounter an Error: Cannot apply unknown utility class error in files using @apply.

Starting with TailwindCSS v4, theme variables, custom utilities, and custom variants are no longer accessible from stylesheets separate from the main bundled CSS. This affects frameworks like Astro, Svelte, and Vue, where @apply is used inside <style> blocks in single-file components (SFCs). To resolve this, use @reference to explicitly import the main CSS file.

Modify your code as follows:

<div class="text-class">
  <p>text</p>
</div>

<style>
@reference "../../styles/app.css";

.text-class {
  @apply p-2;
}
</style>

With this, my Astro-based blog is now running TailwindCSS v4.

Conclusion

Until now, I had only been using TailwindCSS in a basic manner—looking up utilities and applying them as needed. However, while following the upgrade guide and reviewing the official documentation, I realized I hadn’t been fully utilizing TailwindCSS. Moving forward, I plan to study the documentation carefully and refine my component and style architecture.

Related Posts