---
title: "Tailwind CSS v4 with Vue and Vite: the new setup · vuejs.school"
description: "Tailwind CSS 4.0 replaces the config file with CSS, the three directives with one import, and PostCSS with a Vite plugin. The full setup for a Vue project."
canonical_url: "https://vuejs.school/community/blog/tailwind-css-4-with-vue-and-vite"
meta:
  "og:description": "Tailwind CSS 4.0 replaces the config file with CSS, the three directives with one import, and PostCSS with a Vite plugin. The full setup for a Vue project."
  "og:image": "https://vuejs.school/_og/d/a_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVwIMK3IHZ1ZWpzLnNjaG9vbA%2Cc_OgCard.takumi%2Ctitle_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVw%2Cdescription_~VGFpbHdpbmQgQ1NTIDQuMCByZXBsYWNlcyB0aGUgY29uZmlnIGZpbGUgd2l0aCBDU1MsIHRoZSB0aHJlZSBkaXJlY3RpdmVzIHdpdGggb25lIGltcG9ydCwgYW5kIFBvc3RDU1Mgd2l0aCBhIFZpdGUgcGx1Z2luLiBUaGUgZnVsbCBzZXR1cCBmb3IgYSBWdWUgcHJvamVjdC4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_lilac%2Cp_Ii9jb21tdW5pdHkvYmxvZy90YWlsd2luZC1jc3MtNC13aXRoLXZ1ZS1hbmQtdml0ZSI%2Cs_a8Taf7QLVSxnVPL9.png"
  "og:image:alt": "Tailwind CSS v4 with Vue and Vite: the new setup · vuejs.school"
  "og:image:height": "600"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "Tailwind CSS v4 with Vue and Vite: the new setup · vuejs.school"
  "twitter:image": "https://vuejs.school/_og/d/a_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVwIMK3IHZ1ZWpzLnNjaG9vbA%2Cc_OgCard.takumi%2Ctitle_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVw%2Cdescription_~VGFpbHdpbmQgQ1NTIDQuMCByZXBsYWNlcyB0aGUgY29uZmlnIGZpbGUgd2l0aCBDU1MsIHRoZSB0aHJlZSBkaXJlY3RpdmVzIHdpdGggb25lIGltcG9ydCwgYW5kIFBvc3RDU1Mgd2l0aCBhIFZpdGUgcGx1Z2luLiBUaGUgZnVsbCBzZXR1cCBmb3IgYSBWdWUgcHJvamVjdC4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_lilac%2Cp_Ii9jb21tdW5pdHkvYmxvZy90YWlsd2luZC1jc3MtNC13aXRoLXZ1ZS1hbmQtdml0ZSI%2Cs_a8Taf7QLVSxnVPL9.png"
  "twitter:image:alt": "Tailwind CSS v4 with Vue and Vite: the new setup · vuejs.school"
---

> Index of every page on this site: [llms.txt](https://vuejs.school/llms.txt)

## What shipped in 4.0

The announcement leads with a new engine: full builds up to 5x faster and incremental builds over 100x faster. The median times behind those claims, measured on the team's own Catalyst project, are more useful:

- Full build: 378ms in v3.4, 100ms in v4.0.
- Rebuild that adds new CSS: 44ms to 5ms.
- Rebuild with no new CSS: 35ms to 192µs.

The 100x figure is that last case: a save that only uses classes you have already used finishes in microseconds.

Four changes affect setup, and each has a section below:

- A dedicated Vite plugin, `@tailwindcss/vite`.
- One `@import` line instead of three directives.
- Configuration in CSS with `@theme`, instead of `tailwind.config.js`.
- Automatic detection of template files, with no `content` array.

Underneath, the engine is built on modern CSS: native cascade layers, logical properties, custom properties registered with `@property` (CSS variables with a declared type) and `color-mix()`, which v4 uses for opacity modifiers like `bg-blue-500/50`. Those last two set the browser floor in the next section.

New in the classes you write:

- The default palette moves from `rgb` to `oklch`, using the wider P3 colour range of modern screens for more vivid colours.
- Container queries are in core, and there are 3D transform utilities.
- Linear gradients take angles ( `bg-linear-45`), and radial and conic gradients are new.
- A `starting:` variant transitions an element when it first appears, and a `not-*` variant applies a style when another variant does not match.

## Check browser support before you switch

The [compatibility page](https://tailwindcss.com/docs/compatibility) says the core of v4 depends on Chrome 111, Safari 16.4 and Firefox 128. Those are the first versions that support both `@property` and `color-mix()`, and v4.0 has no fallback mode for anything older.

Chrome 111 and Safari 16.4 came out in March 2023, Firefox 128 in July 2024, so for most apps built in 2025 those versions are fine. If your users include older corporate desktops or old iPads that cannot update Safari, stay on v3.4 for now: your v3 setup keeps working as it is.

Some utilities, such as `field-sizing` and the `starting:` variant, rely on features with limited browser support. Leave those out if the browsers you support lack them.

## Install the Vite plugin

Start from a project created with `npm create vue@latest`, or any Vue and Vite project that does not use Tailwind yet. Install two packages:

```
npm install tailwindcss @tailwindcss/vite
```

Then add the plugin to the Vite config. A create-vue project already has `vue()` and `vueDevTools()` there, so the new lines are the `tailwindcss` import and `tailwindcss()` at the end of `plugins`:

*vite.config.ts*

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

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

There is no PostCSS config to create and no `tailwind.config.js`. The announcement says this plugin performs better than the PostCSS one.

## Replace main.css with one import

A create-vue project imports `src/assets/main.css` from `main.ts`. Replace everything in that file with a single line:

*src/assets/main.css*

```
@import "tailwindcss";
```

In v3 this was three lines: `@tailwind base;`, `@tailwind components;` and `@tailwind utilities;`. In v4 it is a regular CSS `@import`, and Tailwind takes over two jobs that used to need extra PostCSS plugins:

- It bundles any further `@import` rules itself. In v3 that needed `postcss-import`.
- It uses Lightning CSS underneath for vendor prefixes and nesting.

The new `main.css` no longer imports the `base.css` that create-vue ships, so you can delete that file. Run `npm run dev` and the utilities work in every component.

## Add design tokens with @theme

Design tokens, the named values a project agrees on for colours, fonts and spacing, used to live in a JavaScript object. In v4 they are CSS variables inside an `@theme` block, in the same file:

*src/assets/main.css*

```
@import "tailwindcss";

@theme {
  --font-display: "Satoshi", sans-serif;
  --color-brand-500: oklch(0.62 0.17 250);
  --color-brand-700: oklch(0.45 0.15 250);
}
```

The `oklch()` numbers are lightness, chroma (how vivid) and hue. `sans-serif` is the fallback until you load the Satoshi web font, and it has no quotes on purpose: quoted, it would name a font called "sans-serif".

Each variable creates utilities. `--color-brand-500` gives you `bg-brand-500`, `text-brand-500`, `border-brand-500` and every other colour utility. `--font-display` gives you `font-display`. The announcement shows the same pattern for breakpoints (`--breakpoint-3xl: 1920px`) and easing curves.

Tailwind also writes the variables into the built CSS as ordinary custom properties on `:root`, so `var(--color-brand-500)` works in a component's `<style>` block or an inline style.

## Use the token in a component

A pricing card with a heading, some text and a button, using the tokens from above:

*src/components/PlanCard.vue*

```
<script setup lang="ts">
defineProps<{
  name: string
  price: number
}>()
</script>

<template>
  <article class="rounded-xl border border-slate-200 bg-white p-6 shadow-sm">
    <h2 class="font-display text-xl font-semibold text-slate-900">{{ name }}</h2>
    <p class="mt-2 text-slate-600">{{ price }} a month, cancel any time.</p>
    <button
      type="button"
      class="mt-4 rounded-lg bg-brand-500 px-4 py-2 text-white hover:bg-brand-700"
    >
      Choose {{ name }}
    </button>
  </article>
</template>
```

Import it into `App.vue` and render `<PlanCard name="Pro" :price="12" />`. If the button is blue, the `@theme` block is working: `bg-brand-500` exists only because of it.

`border-slate-200` is written out on purpose. In v4 the default border colour is `currentColor`, not `gray-200` as it was in v3, so a bare `border` takes the text colour unless you give it one.

## How Tailwind finds your classes

Tailwind only generates the classes you use, so it has to read your files. In v3 you listed the paths in a `content` array, and forgetting a folder meant missing styles. In v4 Tailwind finds template files on its own. The announcement says it skips anything in `.gitignore`, and binary files such as images and archives.

If some of your templates live somewhere Tailwind skips, such as a component library inside `node_modules`, point at it from CSS with `@source`:

*src/assets/main.css*

```
@import "tailwindcss";
@source "../../node_modules/@my-company/ui";
```

The path is relative to the CSS file. For a normal Vue project with components under `src/`, you will not need `@source` at all.

## Upgrade a v3 project

For existing projects there is an upgrade tool:

```
npx @tailwindcss/upgrade
```

It needs Node 20 or newer, and it stops if git shows uncommitted changes, so commit first. The [upgrade guide](https://tailwindcss.com/docs/upgrade-guide) recommends running it on a new branch and reviewing the diff.

The tool updates your dependencies, moves your config into `@theme`, swaps the directives for the import, and renames the utilities whose scale shifted. Those renames are what to check in the diff:

- `shadow-sm` is now `shadow-xs`, and the old `shadow` is `shadow-sm`. `blur` and `drop-shadow` shift the same way.
- `rounded-sm` is now `rounded-xs`, and the old `rounded` is `rounded-sm`.
- `ring` is now `ring-3`, because the default ring width went from 3px to 1px. The default ring colour also changed from `blue-500` to `currentColor`, so add `ring-blue-500` where you relied on it.
- `outline-none` is now `outline-hidden`.

The tool deletes `tailwind.config.js` after moving its settings into CSS. If it cannot convert the file, it says so and keeps it, loaded from your CSS with an `@config` line. Keep it until you have moved those settings by hand.

The tool moves your PostCSS setup to the new `@tailwindcss/postcss` package, not to the Vite plugin. To switch, install and add `@tailwindcss/vite` as shown above, then remove Tailwind from `postcss.config.js`, or delete the file if nothing else is in it.

**Check it stuck**3 questions from the Tailwind CSS with Vue quiz.

[**Practice now**](https://vuejs.school/learn/styling/tailwind-css-with-vue?tab=quiz)

**Was this helpful?**

## **Keep reading**

[Tutorial · 7 min read**Component libraries in 2026: Nuxt UI, PrimeVue, Vuetify and when to use none**](https://vuejs.school/community/blog/component-libraries-in-2026) [Tutorial · 7 min read**Accessible components: focus, keyboard and ARIA**](https://vuejs.school/community/blog/accessible-components-focus-keyboard-and-aria)

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://vuejs.school/#website","@type":"WebSite","description":"A free AI-instructed school for Vue.js. Short tutorials, runnable code and quizzes that adapt to you.","name":"vuejs.school","url":"https://vuejs.school/","publisher":{"@id":"https://vuejs.school/#identity"}},{"@id":"https://vuejs.school/community/blog/tailwind-css-4-with-vue-and-vite#webpage","@type":"WebPage","dateModified":"2026-10-27T19:31:40.253Z","datePublished":"2025-01-28","description":"Tailwind CSS 4.0 replaces the config file with CSS, the three directives with one import, and PostCSS with a Vite plugin. The full setup for a Vue project.","name":"Tailwind CSS v4 with Vue and Vite: the new setup","url":"https://vuejs.school/community/blog/tailwind-css-4-with-vue-and-vite","breadcrumb":{"@id":"https://vuejs.school/community/blog/tailwind-css-4-with-vue-and-vite#breadcrumb"},"isPartOf":{"@id":"https://vuejs.school/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://vuejs.school/community/blog/tailwind-css-4-with-vue-and-vite"]}],"primaryImageOfPage":{"@id":"https://vuejs.school/#logo"}},{"@id":"https://vuejs.school/#identity","@type":"Organization","description":"A free AI-instructed school for Vue.js. Short tutorials, runnable code and quizzes that adapt to you.","name":"vuejs.school","url":"https://vuejs.school","logo":{"@id":"https://vuejs.school/#logo"}},{"@id":"https://vuejs.school/community/blog/tailwind-css-4-with-vue-and-vite#article","dateModified":"2026-10-27T19:31:40.253Z","datePublished":"2025-01-28","description":"Tailwind CSS 4.0 replaces the config file with CSS, the three directives with one import, and PostCSS with a Vite plugin. The full setup for a Vue project.","headline":"Tailwind CSS v4 with Vue and Vite: the new setup","inLanguage":"en","isAccessibleForFree":true,"thumbnailUrl":"https://vuejs.school/_og/d/a_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVwIMK3IHZ1ZWpzLnNjaG9vbA%2Cc_OgCard.takumi%2Ctitle_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVw%2Cdescription_~VGFpbHdpbmQgQ1NTIDQuMCByZXBsYWNlcyB0aGUgY29uZmlnIGZpbGUgd2l0aCBDU1MsIHRoZSB0aHJlZSBkaXJlY3RpdmVzIHdpdGggb25lIGltcG9ydCwgYW5kIFBvc3RDU1Mgd2l0aCBhIFZpdGUgcGx1Z2luLiBUaGUgZnVsbCBzZXR1cCBmb3IgYSBWdWUgcHJvamVjdC4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_lilac%2Cp_Ii9jb21tdW5pdHkvYmxvZy90YWlsd2luZC1jc3MtNC13aXRoLXZ1ZS1hbmQtdml0ZSI%2Cs_a8Taf7QLVSxnVPL9.png","@type":["Article","BlogPosting"],"articleSection":["Release notes"],"author":{"@id":"https://vuejs.school/#identity"},"image":{"@id":"https://vuejs.school/#/schema/image/1"},"isPartOf":{"@id":"https://vuejs.school/community/blog/tailwind-css-4-with-vue-and-vite#webpage"},"mainEntityOfPage":{"@id":"https://vuejs.school/community/blog/tailwind-css-4-with-vue-and-vite#webpage"},"publisher":{"@id":"https://vuejs.school/#identity"}},{"@id":"https://vuejs.school/community/blog/tailwind-css-4-with-vue-and-vite#breadcrumb","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","name":"Blog","item":"https://vuejs.school/community/blog","position":1},{"@type":"ListItem","name":"Tailwind CSS v4 with Vue and Vite: the new setup","position":2}]},{"@id":"https://vuejs.school/#logo","@type":"ImageObject","caption":"vuejs.school","contentUrl":"https://vuejs.school/apple-touch-icon.png","inLanguage":"en","url":"https://vuejs.school/apple-touch-icon.png"},{"@id":"https://vuejs.school/#/schema/image/1","@type":"ImageObject","contentUrl":"https://vuejs.school/_og/d/a_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVwIMK3IHZ1ZWpzLnNjaG9vbA%2Cc_OgCard.takumi%2Ctitle_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVw%2Cdescription_~VGFpbHdpbmQgQ1NTIDQuMCByZXBsYWNlcyB0aGUgY29uZmlnIGZpbGUgd2l0aCBDU1MsIHRoZSB0aHJlZSBkaXJlY3RpdmVzIHdpdGggb25lIGltcG9ydCwgYW5kIFBvc3RDU1Mgd2l0aCBhIFZpdGUgcGx1Z2luLiBUaGUgZnVsbCBzZXR1cCBmb3IgYSBWdWUgcHJvamVjdC4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_lilac%2Cp_Ii9jb21tdW5pdHkvYmxvZy90YWlsd2luZC1jc3MtNC13aXRoLXZ1ZS1hbmQtdml0ZSI%2Cs_a8Taf7QLVSxnVPL9.png","inLanguage":"en","url":"https://vuejs.school/_og/d/a_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVwIMK3IHZ1ZWpzLnNjaG9vbA%2Cc_OgCard.takumi%2Ctitle_~VGFpbHdpbmQgQ1NTIHY0IHdpdGggVnVlIGFuZCBWaXRlOiB0aGUgbmV3IHNldHVw%2Cdescription_~VGFpbHdpbmQgQ1NTIDQuMCByZXBsYWNlcyB0aGUgY29uZmlnIGZpbGUgd2l0aCBDU1MsIHRoZSB0aHJlZSBkaXJlY3RpdmVzIHdpdGggb25lIGltcG9ydCwgYW5kIFBvc3RDU1Mgd2l0aCBhIFZpdGUgcGx1Z2luLiBUaGUgZnVsbCBzZXR1cCBmb3IgYSBWdWUgcHJvamVjdC4%2Ceyebrow_~UmVsZWFzZSBub3RlcyDCtyA2IG1pbiByZWFk%2Ctint_lilac%2Cp_Ii9jb21tdW5pdHkvYmxvZy90YWlsd2luZC1jc3MtNC13aXRoLXZ1ZS1hbmQtdml0ZSI%2Cs_a8Taf7QLVSxnVPL9.png"}]}
```