Tailwind CSS v4 Vite Plugin — Deep Integration and Configuration
In this tutorial, you will learn about Tailwind CSS v4 Vite Plugin. We cover key concepts, practical examples, and best practices to help you master this topic.
The @tailwindcss/vite plugin integrates Tailwind CSS v4 deeply with Vite's build system, providing instant HMR, Lightning CSS processing, and automatic content detection.
What You'll Learn
You will learn how to install and configure the Vite plugin, leverage HMR for instant CSS updates, optimize production builds, and customize the plugin's behavior.
Why It Matters
The Vite plugin is the recommended setup for most projects. DodaTech uses it for all Vite-based projects (React, Vue, Svelte), enabling sub-second HMR.
Real-World Use
Doda Browser's extension uses @tailwindcss/vite for HMR that reflects CSS changes in under 50ms, enabling rapid UI iteration.
flowchart LR
A[Standalone CLI] --> B[Vite Plugin]
B --> C[Installation]
B --> D[HMR]
B --> E[Production Build]
B --> F[Customization]
style B fill:#38bdf8,stroke:#0284c7,color:#fff
style C fill:#22c55e,stroke:#16a34a,color:#fff
Installation
npm create vite@latest my-app -- --template react
cd my-app
npm install tailwindcss @tailwindcss/vite
// vite.config.js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [react(), tailwindcss()],
})
/* src/index.css */
@import "tailwindcss";
@theme {
--color-brand: #7c3aed;
}
Expected output: Three steps to set up Tailwind v4 with Vite: install, add plugin to config, add @import in CSS.
Hot Module Replacement (HMR)
/* The Vite plugin enables instant CSS updates */
/* 1. Change a class in your component */
/* Before: */
<div class="bg-blue-500 text-white p-4">Button</div>
/* After: -- browser updates instantly without full reload */
<div class="bg-green-500 text-white p-4">Button</div>
/* 2. Change @theme values */
@theme {
--color-brand: #7c3aed;
}
/* Change to: */
@theme {
--color-brand: #6366f1; /* Indigo */
}
/* All brand-* utilities update instantly */
Expected output: CSS class changes and @theme modifications reflect in the browser within milliseconds, without page reload.
Production Build Optimization
// vite.config.js -- optimized for production
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [react(), tailwindcss()],
build: {
// Target modern browsers for smaller CSS
target: 'es2020',
// CSS minification via Lightning CSS (default)
cssMinify: 'lightningcss',
// CSS code splitting
cssCodeSplit: true,
// Generate source maps only in dev
sourcemap: process.env.NODE_ENV !== 'production',
},
css: {
lightningcss: {
// Enable CSS nesting
drafts: {
nesting: true,
},
// Include browser targets for autoprefixing
browserslist: 'last 2 versions',
},
},
})
Expected output: Production builds are automatically optimized with Lightning CSS Minification, Code Splitting, and browser targeting.
Content Detection
// The plugin automatically detects content files based on Vite's module graph
// No content array needed -- all imported files are scanned
// However, you can customize scanning:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
tailwindcss({
// Custom scanning options
scan: {
// Include/exclude patterns
include: ['**/*.{html,js,jsx,ts,tsx}'],
exclude: ['**/node_modules/**', '**/dist/**'],
},
}),
],
})
Expected output: Content scanning is automatic through Vite's module graph. Custom include/exclude patterns provide fine-grained control.
Plugin Options
// vite.config.js -- full plugin options
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [
tailwindcss({
// Path to config file (optional, CSS @theme is preferred)
config: './tailwind.config.js',
// Custom CSS input path (optional)
css: './src/styles/tailwind.css',
// Scanning configuration
scan: {
include: ['**/*.{html,js,jsx,ts,tsx}'],
exclude: ['**/node_modules/**'],
},
// Disable HMR for specific environments
hotReload: process.env.NODE_ENV !== 'production',
}),
],
})
Expected output: Plugin options provide configuration for config file path, CSS input, scanning, and HMR behavior.
Environment-Specific Configuration
// vite.config.js -- environment-based configuration
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig(({ mode }) => ({
plugins: [
tailwindcss({
// Development optimizations
hotReload: mode === 'development',
// Production-specific
scan: {
exclude: mode === 'production'
? ['**/node_modules/**', '**/*.test.*', '**/*.spec.*']
: ['**/node_modules/**'],
},
}),
],
build: {
// Enable detailed CSS analysis in production
reportCompressedSize: mode === 'production',
cssMinify: 'lightningcss',
},
}))
Expected output: Configuration adapts based on the build mode. Development gets HMR. Production gets strict scanning and detailed reports.
Common Mistakes
1. Adding PostCSS Plugin Alongside @tailwindcss/vite
The @tailwindcss/vite plugin replaces PostCSS for Tailwind processing. Do not also add @tailwindcss/postcss in PostCSS config.
2. Not Installing tailwindcss Package
The @tailwindcss/vite plugin requires tailwindcss as a peer dependency. Install both packages.
3. Multiple Tailwind Imports
Only one @import "tailwindcss" should exist. Multiple imports cause duplicate CSS.
4. Forgetting to Restart Dev Server
After adding the Vite plugin, restart the dev server. HMR will not work until the plugin is active.
5. Incorrect Plugin Order
The tailwindcss() plugin should be added after framework plugins (react(), vue()) for proper processing order.
Practice Questions
What package provides Vite integration? @tailwindcss/vite. Add it to the plugins array in vite.config.js.
How does HMR work with the plugin? Changes to CSS and @theme reflect instantly in the browser without page reload.
Do you need a content array in v4? No. The plugin automatically scans all files Vite processes.
What CSS minifier does v4 use? Lightning CSS (--cssMinify: 'lightningcss'), which is the default.
What is the recommended plugin order? Framework plugins first (react, vue), then tailwindcss().
Challenge
Set up a Vite + React project with @tailwindcss/vite: configure custom @theme with 3 brand colors, verify HMR works by changing a class and a theme value, build for production, and analyze the output CSS size.
FAQ
Mini Project
Create a Vite + React project with @tailwindcss/vite: add custom @theme tokens, build 3 components (Button, Card, Modal) using Tailwind utilities, enable HMR and verify instant updates, configure production build optimization, and measure CSS bundle size.
What's Next
Now master IDE Support for editor integration and IntelliSense. Then explore Browser Support for compatibility considerations.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro