Migrating Blazor to Tailwind CSS 4
A comprehensive guide to adopting Tailwind CSS 4 in Blazor, leveraging CSS-first configuration and the new JIT engine for a streamlined frontend workflow.
When I first configured Tailwind CSS v4 for our Blazor Server project, I expected a straightforward migration from v3. Instead, I encountered a cascade of breaking changes: every tailwind.config.js customization needed to be translated into CSS @theme directives, our custom color palette references broke across dozens of components, and the content path scanning worked differently enough that half our utility classes were being purged in production. The migration took a full week of methodical file-by-file conversion, but the result was a dramatically simpler build pipeline and noticeably faster compile times.
Introduction
Tailwind CSS v4 introduces a paradigm shift by moving configuration from JavaScript (tailwind.config.js) directly into CSS. For Blazor developers, this simplifies the build pipeline significantly. We no longer need complex NPM build steps or PostCSS configs cluttering our .NET projects.
Why Tailwind v4 for Blazor Matters:
- Simplified Toolchain: The standalone CLI or simple PostCSS plugin is much lighter.
- Performance: The new engine is rewritten in Rust, offering instant build times.
- CSS-First Configuration: Configure your theme, fonts, and breakpoints right where you use them—in your CSS.
What We’ll Build
We will migrate our Blazor frontend to Tailwind v4. You will learn how to:
- Setup the CSS Input: rigorous use of
@themeand@utility. - Integrate with Blazor: Watching for changes and serving the output.
- Optimize for Production: Minification and cache busting.
Architecture Overview
Network traffic for styles during development is served directly from the compiled CSS file.
[Tailwind CSS v4 Upgrade Guide] — Tailwind Labs , 2025-01-22flowchart LR
Dev[Developer] -->|Edits| Razor[Component.razor]
Dev -->|Edits| CSS[input.css]
subgraph "Build Process"
CSS -->|@theme directives| TW[Tailwind v4 Engine]
TW -->|Compiles| Output[app.css]
end
Output -->|Link Tag| BlazorApp[Blazor Server App]
classDef primary fill:#7c3aed,color:#fff
classDef secondary fill:#06b6d4,color:#fff
classDef db fill:#f43f5e,color:#fff
classDef warning fill:#fbbf24,color:#000
class TW secondary
class BlazorApp primary
class Dev warning
Implementation
1. The New Input CSS
Delete your tailwind.config.js. Create a Styles/input.css file. This is now your configuration source.
@import "tailwindcss";
@theme {
/* Brand Colors */
--color-robin-50: #f0f9ff;
--color-primary-500: #0ea5e9;
--color-robin-900: #0c4a6e;
/* Typography */
--font-sans: "Inter", system-ui, sans-serif;
/* Animations */
--animate-fade-in: fade-in 0.3s ease-out;
@keyframes fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
}
/* Custom Utilities */
@utility .btn-primary {
@apply px-4 py-2 bg-primary-500 text-white rounded hover:bg-robin-600 transition-colors;
} 2. NPM Scripts
We use a simplified package.json to run the Tailwind CLI.
{
"scripts": {
"css:build": "tailwindcss -i ./Styles/input.css -o ./wwwroot/css/app.css --minify",
"css:watch": "tailwindcss -i ./Styles/input.css -o ./wwwroot/css/app.css --watch"
},
"devDependencies": {
"tailwindcss": "^4.0.0"
}
} 3. Blazor Integration
In your App.razor (or _Host.cshtml), ensure you link to the generated output.
<head>
<link href="css/app.css" rel="stylesheet" />
</head> Conclusion
Migrating to Tailwind CSS 4 has reduced our configuration boilerplate and improved build speeds. The “CSS-first” approach feels more natural for styling and keeps our architecture clean and focused on standard web technologies.
Looking back at the migration, the week of effort was well worth it. Build times dropped from several seconds to under 200 milliseconds, the removal of tailwind.config.js eliminated an entire category of configuration drift between environments, and the team found the CSS-native @theme syntax easier to reason about than the JavaScript configuration object. The key lesson was to migrate methodically: convert the theme tokens first, then update utility references, and finally remove the old configuration files only after verifying production builds.
Next Steps
- Integrate Tailwind v4 with our glassmorphism design system for consistent glass utility classes.
- Set up CI pipeline caching for the Tailwind build output to speed up deployments.
- Explore Tailwind v4’s new
@variantdirective for custom responsive and state variants.