Tailwind CSS v4 Deployment and Optimization — Production Guide
In this tutorial, you will learn about Tailwind CSS v4 Deployment and Optimization. We cover key concepts, practical examples, and best practices to help you master this topic.
Tailwind CSS v4 deployment focuses on production optimization with Lightning CSS minification, automatic content detection, zero-config purging, and framework-specific deployment strategies for Vite, Next.js, Remix, and static sites.
What You'll Learn
You will learn how to configure production builds, optimize CSS output with Lightning CSS, set up CDN delivery, deploy with various frameworks, and monitor build performance.
Why It Matters
Production CSS bundles directly impact page load time and user experience. DodaTech's v4 production builds average 6KB gzipped per page, achieved through automatic purging and Lightning CSS optimization.
Real-World Use
The DodaTech tutorial site deploys Tailwind v4 via Vite to Netlify, with automatic CSS purging producing a 5.8KB production bundle that serves over 15,000 pages.
flowchart LR
A[Source CSS] --> B[Tailwind v4 Build]
B --> C[Content Detection]
C --> D[Lightning CSS]
D --> E[Minified CSS]
E --> F[CDN Deploy]
B --> G[Purge Unused]
G --> D
style B fill:#38bdf8,stroke:#0284c7,color:#fff
style D fill:#22c55e,stroke:#16a34a,color:#fff
Production Build Configuration
# Install production dependencies
npm install -D @tailwindcss/vite lightningcss
# Build with Vite
npx vite build
# Build with CLI
npx @tailwindcss/cli -i ./src/input.css -o ./dist/output.css --minify
Expected output: Both commands produce optimized CSS bundles. Vite's build integrates with the full framework pipeline. The CLI is suitable for simple static sites.
// vite.config.js — optimized production build
import tailwindcss from "@tailwindcss/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [tailwindcss()],
build: {
cssMinify: "lightningcss",
minify: "esbuild",
rollupOptions: {
output: {
manualChunks: undefined,
inlineDynamicImports: true,
},
},
cssCodeSplit: false,
},
});
Expected output: This configuration uses Lightning CSS for CSS minification (matching Tailwind's internal engine), disables CSS code splitting for single-file output, and uses esbuild for JavaScript minification.
Automatic Content Detection
@import "tailwindcss";
/* v4 detects content paths automatically — no tailwind.config needed */
/* But you can specify content paths explicitly if needed */
@source "./src/**/*.html";
@source "./src/**/*.{js,jsx,ts,tsx}";
@source "!./src/excluded/**";
Expected output: The @source directive tells Tailwind v4 where to scan for class usage. The ! prefix excludes directories. Without @source, v4 scans all files in the project root.
@import "tailwindcss";
/* Multiple source paths for monorepo */
@source "../../packages/ui/src/**/*.tsx";
@source "../docs/**/*.md";
@source "./app/**/*.html";
/* Source with specific extensions */
@source "./src" {
extensions: ["html", "jsx", "tsx"];
}
Expected output: In Monorepo setups, @source can reference packages outside the current directory. The extensions option restricts which file types are scanned.
CSS Output Optimization
@import "tailwindcss";
@import "tailwindcss/theme" layer(theme);
@import "tailwindcss/preflight" layer(base);
@import "tailwindcss/utilities" layer(utilities);
/* Only the utilities you use are generated — no manual purge config needed */
Expected output: Tailwind v4 automatically generates only the CSS classes detected in the scanned source files. No separate purge or content configuration is required.
@import "tailwindcss";
/* Disable unused layer generation for smaller output */
@config {
layers: {
theme: true;
base: true;
components: true;
utilities: true;
}
}
Expected output: The @config block allows granular control over which CSS layers to include. Disabling unused layers can reduce bundle size further for component libraries.
Framework-Specific Deployment
// Netlify — netlify.toml
[build]
command = "npm run build"
publish = "dist"
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
Expected output: Netlify deploys the Vite output directory. Static assets get immutable cache headers for optimal CDN Caching.
# Vercel — vercel.json
{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"headers": [
{
"source": "/assets/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
}
]
}
Expected output: Vercel configuration matches Netlify. Both platforms support immutable asset caching for optimal CDN performance.
# Docker multi-stage build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Expected output: The multi-stage Docker build produces a minimal production image (~25MB) with the Tailwind v4 site served by Nginx.
CDN Delivery
<!-- Tailwind v4 CDN for prototyping -->
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<!-- With specific version -->
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.0.0/dist/cdn.min.js"></script>
Expected output: The CDN script loads Tailwind v4 directly in the browser. Suitable for prototyping but not recommended for production due to runtime overhead.
<!-- Production: preload critical CSS -->
<link rel="preload" href="/assets/main-Bd4eR6.css" as="style">
<link rel="stylesheet" href="/assets/main-Bd4eR6.css">
<!-- Inline critical CSS for above-the-fold content -->
<style>
/* Inline minimal critical styles */
.flex { display: flex; }
.grid { display: grid; }
.text-center { text-align: center; }
@media (min-width: 768px) {
.md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
</style>
Expected output: Preloading critical CSS and inlining above-the-fold styles improves Largest Contentful Paint (LCP). The main stylesheet loads asynchronously after the critical CSS is applied.
Common Mistakes
1. Not Setting NODE_ENV=production
Without production mode, Tailwind v4 includes debug information and development-only variants. Always set NODE_ENV=production in CI/CD environments.
2. Forgetting @source Directives in Monorepos
In monorepo setups, Tailwind v4 cannot automatically detect files in sibling packages. Use explicit @source directives for all packages that use Tailwind classes.
3. Not Caching Static Assets
Without Cache-Control: immutable headers, browsers re-request CSS assets on every visit. Configure CDN caching for fingerprinted assets.
4. Using CDN Script in Production
The CDN script processes styles at runtime, adding ~50KB of JavaScript and delaying rendering. Use the build-based approach for production.
5. Missing Build Error Handling
Build errors in CI/CD can fail silently. Add proper error handling and fail-fast mechanisms in deployment scripts.
Practice Questions
How does Tailwind v4 detect which classes to include? It scans source files automatically for class name usage. The
@sourcedirective specifies which directories to scan.What is the role of Lightning CSS in production builds? Lightning CSS minifies the generated CSS, removes unused rules, and applies vendor prefixes, replacing the previous PostCSS-based pipeline.
How do you configure CDN caching for Tailwind assets? Set
Cache-Control: public, max-age=31536000, immutablefor fingerprinted asset files in your CDN or hosting platform.What is the
@sourcedirective used for? It explicitly tells Tailwind v4 where to scan for class usage, essential in monorepos and projects with non-standard directory structures.Why avoid the CDN script in production? The CDN script processes styles at runtime, adding JavaScript overhead, delaying rendering, and preventing static optimization.
Challenge
Set up a complete CI/CD pipeline for a Tailwind v4 project that includes: production build with Lightning CSS minification, content scanning across a monorepo with 3 packages, Docker multi-stage build for container deployment, CDN cache headers configuration, and build size monitoring with alerts if CSS exceeds 15KB.
FAQ
Mini Project
Create a deployment pipeline for a Tailwind v4 marketing site with: Vite production build configuration, @source directives for a monorepo with two packages, Docker multi-stage build to Nginx, Netlify deploy configuration with immutable caching, and a build-size check in CI that fails if the CSS bundle exceeds 12KB gzipped.
What's Next
Now apply everything in the Tailwind v4 Project where you will build a complete dashboard from scratch. Then explore CSS for deeper understanding of the foundational technology.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro