Home / Blog / Tailwind CSS v4 with Vue 3: Setup, Config, and Migration Guide
Tailwind CSS v4 with Vue 3: Setup, Config, and Migration Guide

Tailwind CSS v4 with Vue 3: Setup, Config, and Migration Guide

Tailwind CSS v4 changed how you wire Tailwind into a project. There is no tailwind.config.js by default, no postcss.config.js in a Vite app, and no @tailwind directives. You install one Vite plugin, add a single @import line to your CSS, and configure your design tokens in CSS with the @theme directive.

This guide is the current, end-to-end setup for Tailwind v4 in a Vue 3 + Vite project: install, config, and the CSS-first workflow. If you are moving an existing Vue app from v3, jump to the migration checklist, which covers the renamed utilities and the one gotcha that trips up every Vue project: using @apply inside a single-file component <style> block.

Complete Vue 3 + Vite + Tailwind v4 Setup

Setting up Tailwind CSS v4 in a Vue 3 project using Vite is faster and simpler than ever.

Step 1: Create a Vue Project

If you don't have an existing project, scaffold a new Vue 3 application using the official create-vue initializer:

npm create vue@latest my-tailwind-app
cd my-tailwind-app
npm install

Step 2: Install Tailwind CSS v4 and the Vite Plugin

In Tailwind v4, the first-party @tailwindcss/vite plugin is the recommended path for Vite applications (replacing PostCSS, autoprefixer, and manual tailwind.config.js wiring):

npm install tailwindcss @tailwindcss/vite

Step 3: Register the Plugin in vite.config.ts

Add the @tailwindcss/vite plugin to your Vite configuration file (vite.config.ts or vite.config.js):

import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
  plugins: [
    vue(),
    tailwindcss(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  },
})

Learn more about optimizing build tools in Vue School's Rapid Development with Vite course.

Step 4: Import Tailwind in Your Main Stylesheet

In your main CSS file (e.g., src/assets/main.css), replace the old @tailwind base; @tailwind components; @tailwind utilities; directives with a single @import line:

/* src/assets/main.css */
@import "tailwindcss";

Step 5: Import the Stylesheet in src/main.ts

Ensure your stylesheet is imported in your application entry point (src/main.ts or src/main.js):

import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

That is the entire installation! No tailwind.config.js, no PostCSS configuration file, and no content array setup required—Tailwind v4 automatically scans your template files for class names.

<!-- App.vue -->
<template>
  <h1 class="bg-blue-500 text-white p-5 text-2xl font-bold rounded-lg">
    Hello Tailwind CSS v4 + Vue 3!
  </h1>
</template>

Step 6: Configure Design Tokens in CSS with @theme

Tailwind v4 introduces a CSS-first configuration model. Instead of extending themes in tailwind.config.js, you define theme variables inside an @theme block right in your CSS file:

/* src/assets/main.css */
@import "tailwindcss";

@theme {
  /* Define custom color utilities (e.g., bg-brand, text-brand, border-brand) */
  --color-brand: #16a34a;
  --color-primary: oklch(0.53 0.12 118.34);

  /* Override theme breakpoints */
  --breakpoint-sm: 30rem;
  --breakpoint-3xl: 120rem;

  /* Custom fonts */
  --font-display: "Satoshi", sans-serif;
}

These theme variables generate utility classes automatically while compiling to native CSS custom properties (var(--color-brand)), making them accessible in inline styles, CSS, or JavaScript:

<div style="background-color: var(--color-primary)">
  <p class="text-brand font-display">Styled with Tailwind v4 theme variables!</p>
</div>

Step 7: The Vue-Specific Gotcha: @apply in Single-File Component <style> Blocks

In Tailwind v4, single-file component (SFC) <style> blocks do not automatically inherit your custom @theme variables or custom utility definitions. If you use @apply or custom theme tokens inside a .vue component's <style> block, add the @reference directive pointing to your main CSS file:

<template>
  <button class="btn-primary">Click Me</button>
</template>

<style scoped>
@reference "../assets/main.css";

.btn-primary {
  @apply bg-brand text-white px-4 py-2 rounded-lg transition-colors hover:bg-brand/90;
}
</style>

Note: If you are only using default Tailwind theme values without custom tokens, @reference "tailwindcss"; can be used instead.

Tailwind v3 to v4 Migration Checklist for Vue Projects

If you are upgrading an existing Vue 3 project from Tailwind v3 to v4, follow this step-by-step checklist:

Automated Migration

Run the official upgrade tool on a clean git branch:

npx @tailwindcss/upgrade

The upgrade tool automatically updates dependencies, migrates your tailwind.config.js settings into @theme directives in your main CSS file, and converts deprecated template utility names.

Manual Gotchas & Verification for Vue Apps

  1. Directives Syntax: Replace @tailwind base; @tailwind components; @tailwind utilities; with @import "tailwindcss";.
  2. Config Location: Move theme.extend properties from tailwind.config.js into your main CSS file under @theme. (If you must keep a JS config, use the @config directive).
  3. No PostCSS Config: Remove postcss.config.js, autoprefixer, and postcss-import if migrating to @tailwindcss/vite.
  4. Renamed Utility Scales:
    • shadow became shadow-sm (and old shadow-sm became shadow-xs).
    • rounded became rounded-sm (and old rounded-sm became rounded-xs).
    • The blur scale shifted similarly.
  5. Ring Width Default: ring alone now draws a 1px ring instead of 3px. Use ring-3 to preserve the v3 appearance.
  6. Default Border & Ring Color: Default border and ring colors changed to currentColor (previously gray-200 and blue-500). Ensure explicit border colors (e.g., border-gray-200) are specified.
  7. Outline Utility Rename: outline-none is now outline-hidden (use outline-none only when resetting focus rings).
  8. Opacity Utilities: Utility classes like bg-opacity-* and text-opacity-* are removed. Use the opacity slash syntax (e.g., bg-black/50, text-brand/80).
  9. Flex Utilities: flex-shrink-* and flex-grow-* have been shortened to shrink-* and grow-*.
  10. CSS Variable Arbitrary Syntax: Arbitrary CSS variable values now use parentheses: bg-(--my-color) instead of bg-[var(--my-color)] or bg-[--my-color].
  11. Component @apply References: Grep your codebase for @apply in .vue files and ensure @reference "../assets/main.css"; is added to component <style> blocks.
  12. Modern Browser Target: Tailwind v4 targets modern evergreen browsers supporting @property and color-mix().

Starting a new Vue 3 project? Use the @tailwindcss/vite plugin and CSS-first config from day one. Skip tailwind.config.js entirely and put your tokens in @theme.

Migrating an existing Vue app from v3? Run npx @tailwindcss/upgrade on a branch first, then review component styles against the 12-point checklist above.

What's New in Tailwind CSS v4 for Vue Developers

Beyond the setup overhaul, Tailwind CSS v4 includes exciting utility features perfect for modern Vue applications:

1. Built-in Container Queries

Tailwind v4 natively supports container queries without requiring external plugins. Here is an example of an adaptive PostCard.vue component:

<!-- PostCard.vue -->
<template>
  <article class="@container bg-white rounded-lg shadow-sm">
    <!-- Card content adapts based on container width -->
    <div class="@md:flex @md:items-center p-4 gap-4">
      <img :src="post.image" class="@md:w-1/3 w-full rounded-lg object-cover" />
      <h2 class="text-xl font-bold text-gray-900">{{ post.title }}</h2>
    </div>
  </article>
</template>

<script setup lang="ts">
defineProps<{
  post: {
    title: string
    image: string
  }
}>()
</script>

When placed inside a container with restricted width, the card automatically displays the stacked layout regardless of the viewport size:

<div class="w-96">
  <PostCard :post="samplePost" />
</div>

2. 3D Transform Utilities

Tailwind v4 introduces utilities for styling in 3D space:

<div class="perspective-distant">
  <PostCard class="rotate-x-51 rotate-z-43 transform-3d"/>
</div>

3. Conic, Radial, and Linear Gradients

Create complex gradients effortlessly using dedicated linear angle and radial/conic utilities:

<div class="flex items-center gap-4 mt-10">
  <div class="size-24 rounded-full bg-conic/[in_hsl_longer_hue] from-red-600 to-red-600"></div>
  <div class="size-24 rounded-full bg-radial-[at_25%_25%] from-white to-zinc-900 to-75%"></div>
  <div class="size-24 rounded-full bg-linear-45 from-indigo-500 via-purple-500 to-pink-500"></div>
</div>

4. CSS Starting Style Transitions (Page Load Animation)

Animate elements upon initial load using the starting variant powered by @starting-style:

<div class="starting:opacity-0 transition-all duration-1000 size-24 rounded-full bg-brand"></div>

5. Auto-resizing Textareas

Resize textareas based on their content without JavaScript using field-sizing-content:

<textarea class="field-sizing-content border-gray-300 border w-full rounded-lg p-3"></textarea>

6. The not-* Variant

Exclude specific states or target inverse conditions cleanly:

<RouterLink
  to="/"
  class="transition-colors duration-200 not-hover:text-gray-700 hover:text-brand"
>
  Home
</RouterLink>

Frequently Asked Questions (FAQ)

How do I install Tailwind CSS v4 in a Vue 3 project?

Install tailwindcss and @tailwindcss/vite, add the tailwindcss() plugin to vite.config.ts, then add @import "tailwindcss"; to your main CSS file. There is no tailwind.config.js and no PostCSS config required by default.

Where did tailwind.config.js go in v4?

It is gone by default. You configure design tokens in CSS with the @theme directive inside your main stylesheet. If you need a JavaScript config, you can still load one explicitly with the @config directive.

Why does @apply not work in my Vue component <style> block?

A single-file component <style> block does not see your theme by default in v4. Add @reference "../assets/main.css"; (or @reference "tailwindcss"; for default-only usage) at the top of the <style> block so Tailwind can resolve @apply and custom theme values.

How do I migrate a Vue app from Tailwind v3 to v4?

Run npx @tailwindcss/upgrade on a clean branch and review the diff. Check for renamed shadow, rounded, and blur scales, the updated 1px ring default, explicit border colors, and adding @reference to any Vue component using @apply.

Do I still need PostCSS and Autoprefixer with Tailwind v4 and Vite?

No. The @tailwindcss/vite plugin handles CSS processing natively. You do not need postcss.config.js, autoprefixer, or postcss-import for a standard Vue + Vite project setup.

Conclusion

Tailwind CSS v4 brings a streamlined setup, CSS-first theme configuration, and modern styling features that integrate seamlessly into Vue 3 applications. In this article I’ve reviewed some of the ones I find most interesting but checkout the full release announcement for even more cool changes.

Ready to get started? Just install Tailwind as discussed above or checkout the Nuxt UI v3 (alpha) library, it’s already compatible and it can be installed in a regular Vue or Nuxt project.

How do I install Tailwind CSS v4 in a Vue 3 project?

Install tailwindcss and @tailwindcss/vite, add the tailwindcss() plugin to vite.config.ts, then add @import "tailwindcss"; to your main CSS file. There is no tailwind.config.js and no PostCSS config by default.

Where did tailwind.config.js go in v4?

It is gone by default. You configure design tokens in CSS with the @theme directive. If you need a JS config, you can still load one explicitly with the @config directive.

Why does @apply not work in my Vue component <style> block?

A single-file component <style> block does not see your theme by default in v4. Add @reference "../assets/main.css"; (or @reference "tailwindcss"; for default-only usage) at the top of the block so Tailwind can resolve @apply and theme values.

How do I migrate a Vue app from Tailwind v3 to v4?

Run npx @tailwindcss/upgrade on a branch, then review the diff. Watch for the renamed shadow, rounded, and blur scales, the new 1px ring, the currentColor
border default, and adding @reference to any component that uses @apply.

Do I still need PostCSS and autoprefixer with Tailwind v4 and Vite?

No. The @tailwindcss/vite plugin handles it. You do not need postcss.config.js, autoprefixer, or postcss-import for a standard Vue + Vite setup.

Start learning Vue.js for free

Comments

Latest Vue School Articles

5 Component Design Patterns to Boost Your Vue.js Applications

5 Component Design Patterns to Boost Your Vue.js Applications

5 essential Vue.js component design patterns, including branching components, slots usage, list organization, smart vs dumb components, and form handling - perfect for both Vue beginners and experienced developers looking to improve code maintainability and scalability.
Vibe Coding a Collaborative Editor with Comment Support with Nuxt UI and Jazz

Vibe Coding a Collaborative Editor with Comment Support with Nuxt UI and Jazz

Why I built a Nuxt + Jazz powered real time editor, how you can use it, and a list of takeaways on building with the help of AI.
VueSchool logo

Our goal is to be the number one source of Vue.js knowledge for all skill levels. We offer the knowledge of our industry leaders through awesome video courses for a ridiculously low price.

More than 200.000 users have already joined us. You are welcome too!

Follow us on Social