Hecatronic
599 words
3 minutes
Moving from Tailwind v3 to V4 and @apply

A problem I’ve run into recently is updating some of my sites from version 3 to version 4 of tailwind.
There have been some big changes, especially with the way tailwind handles it’s configuration and how this has an effect on the use of the @apply directive.
From the looks of things some others have run into this problem as well.

From what I understand one of the causes of this is the way tailwind has altered the way it’s configuration is stored.

  • Tailwind v3 originally would read it’s configuration from a js file such as tailwind.config.cjs
  • Tailwind v4 instead now tends to use a css file as it’s primary input for configuration.

This in turn can have a nock on effect on the use of the @apply directive, part of the reason for this being that we no longer have a top level configuration file that’s referenced automatically.

There is supposed to be a backwards compatibility layer using the @config directive, but personally I didn’t have much luck getting this to work.

Creating a new tailwind CSS configuration file#

As a first step we’re going to take the contents of tailwind.config.cjs and convert this into a tailwind-setts.css file.
I did manage to find an online converter but it’s mostly for converting colors, so doesn’t cover everything needed.

With this example I’ll be creating a file located at ./src/assets/tailwind-setts.css to store all the settings that were originally within the js file.
The first line of this file should start with the following to import all of the base / utils / components from within tailwind.

@import "tailwindcss";

@config approach#

Looking through the tailwind docs there is a @config directive we can add to try and import the settings from the original js file, your luck mary vary based on which framework you are using. For me with astro this didn’t seem to work though (perhaps because it’s a cjs file)

@import "tailwindcss";
@config "../../tailwind.config.cjs";

Converting configuration to CSS approach#

So the next approach is to try and convert things directly into css syntax

For me the original configuration looked something like this:

/** @type {import('tailwindcss').Config} */
const defaultTheme = require("tailwindcss/defaultTheme")
module.exports = {
  content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
  darkMode: "class", // allows toggling dark mode manually
  theme: {
    extend: {
      fontFamily: {
        sans: ["Open Sans", "Poppins", "Roboto", "sans-serif", ...defaultTheme.fontFamily.sans],
        bender: ["Bender"],
        benderLight: ["BenderLight"],
      },
    },
  },
  plugins: [require("@tailwindcss/typography")],
}

Converting this to ../../tailwind-setts.css

@import "tailwindcss";
@plugin '@tailwindcss/typography';
@custom-variant dark (&:where(.dark, .dark *));

@theme {
  --font-sans: "Open Sans", "Poppins", "Roboto", "sans-serif";
  --font-bender: "Bender";
  --font-benderLight: "BenderLight";
}

Configuration File Alias#

Next we’re going to add an alias to the tailwind-setts.css file within package.json

  "imports": {
    "#tailwind-setts": "./src/assets/tailwind-setts.css"
  }

From this point forwards we can now use @reference "#tailwind-setts"; instead of trying to reference a relative path.

Switching over the references#

Next we need to add a reference to this settings file wherever we were originally importing tailwind.
The easiest way to do this is to do a search though your source for @tailwind

Replace any of the following

@tailwind base;
@tailwind components;
@tailwind utilities;

With a single one of these

@reference "#tailwind-setts";

Changes for Astro#

As a final step I needed to make some changes for use with astro. Although this will vary of course depending on your framework in use

Replace @astrojs/tailwind with @tailwindcss/vite

pnpm uninstall @astrojs/tailwind
pnpm add @tailwindcss/vite

Next make some changes to the astro configuration astro.config.mjs.
Change the import line for tailwind.

-import tailwind from "@astrojs/tailwind"
+import tailwindcss from '@tailwindcss/vite';
  • Remove tailwind(), from the integrations section
  • Add plugins: [tailwindcss()] to the vite section

Layer Imports#

One thing to watch out for which might impact your site.
If for any reason you were only importing some of the tailwind V3 layers such as avoiding the base layer

@tailwind components;
@tailwind utilities;

This won’t work in Tailwind V4, all 3 layers are now imported with the line

@import "tailwindcss";
Moving from Tailwind v3 to V4 and @apply
https://www.hecatron.com/posts/2025/tailwindv3-v4md/
Author
Hecatronic
Published at
2025-10-27