Tailbreeze

Zero-config Tailwind CSS integration for ASP.NET Core. Auto-installs the standalone CLI, watches for changes in development, and builds optimized CSS for production. Supports Tailwind v3 LTS and v4 stable. No Node.js required.

Zero Config
Works Out of Box
No Node.js
Standalone CLI
Hot Reload
Dev Experience
v3 & v4
Tailwind Support
.NET 8-10
Framework Support

Why Choose Tailbreeze?

The simplest way to add Tailwind CSS to your ASP.NET Core application without the complexity of Node.js tooling.

Zero Configuration

Just add the NuGet package and call AddTailbreeze(). The CLI is auto-downloaded, config files are auto-generated, and hot reload just works.

Hot Reload in Development

Automatically watches your .cshtml and .razor files for changes and rebuilds CSS instantly. See your Tailwind changes without refreshing.

Production Optimized

Minified, tree-shaken CSS at build time via MSBuild integration. Only the classes you use end up in your final bundle.

Get Started in 2 Minutes

Add Tailwind CSS to your ASP.NET Core app with just two packages and three lines of code.

1. Install Packages

# Runtime library
$ dotnet add package Tailbreeze
# Build-time integration
$ dotnet add package Tailbreeze.Build

2. Configure Services

// Program.cs
builder.Services.AddTailbreeze();

3. Add Middleware

// Program.cs
app.UseTailbreeze();

4. Add Stylesheet Link

<!-- _Layout.cshtml or App.razor -->
<link rel="stylesheet" href="/tailbreeze/app.css" />
Program.cs
using Tailbreeze.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add Tailbreeze services
builder.Services.AddTailbreeze();

// ... other services

var app = builder.Build();

// Add Tailbreeze middleware (serves CSS in development)
app.UseTailbreeze();

// ... other middleware

app.Run();

// That's it! Tailbreeze will:
// - Auto-download the Tailwind CLI
// - Create default tailwind.config.js
// - Create default input CSS file
// - Watch for changes in development
// - Build minified CSS for production

Configuration Options

While Tailbreeze works with zero configuration, you can customize every aspect via appsettings.json or code.

appsettings.json

{
  "Tailbreeze": {
    "TailwindVersion": "latest",
    "InputCssPath": "Styles/app.css",
    "OutputCssPath": "css/app.css",
    "ConfigPath": "tailwind.config.js",
    "ServePath": "/tailbreeze/app.css",
    "EnableHotReload": true,
    "AutoInstallCli": true,
    "MinifyCss": null,
    "ContentPaths": [
      "./Pages/**/*.cshtml",
      "./Views/**/*.cshtml"
    ],
    "CliStartupTimeoutSeconds": 60
  }
}

Options Reference

TailwindVersion

"latest" (v4), "4", "3" (v3.4.17 LTS), or specific like "4.0.0"

InputCssPath

Source CSS with @import "tailwindcss" (v4) or @tailwind directives (v3)

OutputCssPath

Compiled CSS output in wwwroot

EnableHotReload

Watch mode in development (default: true)

MinifyCss

null = auto (minify in production only)

CliStartupTimeoutSeconds

CLI startup timeout (default: 60, min: 10)

UseCdnFallback

Fall back to CDN if CLI fails (auto: true in dev)

CliDownloadUrl

Custom URL for CLI download (air-gapped envs)

Framework Integration

Tailbreeze works seamlessly with Razor Pages, MVC, and Blazor applications.

_Layout.cshtml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="/tailbreeze/app.css" />
    <title>@ViewData["Title"]</title>
</head>
<body class="bg-gray-50 min-h-screen">
    <nav class="bg-white shadow-sm">
        <!-- Navigation -->
    </nav>
    <main class="container mx-auto px-4 py-8">
        @RenderBody()
    </main>
</body>
</html>

Index.cshtml

@page
@model IndexModel

<div class="max-w-4xl mx-auto">
    <h1 class="text-4xl font-bold text-gray-900 mb-6">
        Welcome to Tailbreeze
    </h1>

    <div class="bg-white rounded-xl shadow-lg p-8">
        <p class="text-gray-600 mb-4">
            Your ASP.NET Core app is now styled with Tailwind CSS!
        </p>

        <button class="bg-cyan-600 hover:bg-cyan-700
                       text-white px-6 py-3 rounded-lg
                       font-semibold transition-colors">
            Get Started
        </button>
    </div>
</div>

App.razor

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="/" />
    <link rel="stylesheet" href="/tailbreeze/app.css" />
    <HeadOutlet />
</head>
<body class="bg-gray-50 min-h-screen">
    <Routes />
    <script src="_framework/blazor.web.js"></script>
</body>
</html>

Home.razor

@page "/"

<div class="max-w-4xl mx-auto p-8">
    <h1 class="text-4xl font-bold text-gray-900 mb-6">
        Blazor + Tailwind
    </h1>

    <div class="grid md:grid-cols-2 gap-6">
        <div class="bg-white rounded-xl shadow p-6">
            <h2 class="text-xl font-semibold mb-2">Card 1</h2>
            <p class="text-gray-600">Content here</p>
        </div>
        <div class="bg-white rounded-xl shadow p-6">
            <h2 class="text-xl font-semibold mb-2">Card 2</h2>
            <p class="text-gray-600">Content here</p>
        </div>
    </div>
</div>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="/" />
    <link rel="stylesheet" href="css/app.css" />
    <title>Blazor WASM App</title>
</head>
<body class="bg-gray-50">
    <div id="app">Loading...</div>
    <script src="_framework/blazor.webassembly.js"></script>
</body>
</html>

<!-- Note: For standalone WASM, run Tailwind CLI
     during build with Tailbreeze.Build package -->

Build Integration

<!-- .csproj -->
<ItemGroup>
    <PackageReference Include="Tailbreeze.Build"
                      Version="1.0.0" />
</ItemGroup>

<!-- Tailbreeze.Build automatically:
     - Downloads Tailwind CLI at build time
     - Compiles CSS during dotnet build
     - Minifies CSS during dotnet publish
     - No runtime overhead in WASM apps -->

# Build commands
$ dotnet build   # CSS compiled
$ dotnet publish # CSS minified

How It Works

Tailbreeze uses the official Tailwind CSS standalone CLI - no Node.js required.

1. Auto-Download CLI

On first run, Tailbreeze downloads the Tailwind standalone CLI from GitHub. Platform-specific binary (Windows, macOS, Linux).

2. Watch Mode (Dev)

In development, runs CLI in watch mode. Detects changes to .cshtml/.razor files and rebuilds CSS instantly.

3. Build Integration

MSBuild tasks compile and minify CSS during dotnet build/publish. Production CSS is tree-shaken and optimized.

Development Flow

dotnet run
    │
    ├── TailwindHostedService starts
    │   ├── Downloads CLI (if needed)
    │   ├── Creates tailwind.config.js (if needed)
    │   ├── Creates Styles/app.css (if needed)
    │   └── Starts CLI in watch mode
    │
    ├── TailwindMiddleware serves CSS
    │   └── GET /tailbreeze/app.css → wwwroot/css/app.css
    │
    └── File change detected
        └── CLI rebuilds CSS automatically
            └── Browser refresh shows changes

dotnet publish
    │
    └── Tailbreeze.Build MSBuild task
        ├── Downloads CLI (if needed)
        ├── Runs: tailwindcss --minify
        └── Output: wwwroot/css/app.css (minified)

Advanced Features

Tailbreeze includes features for enterprise deployments and special requirements.

Air-Gapped Environments

Host the CLI on your own server for environments without internet access.

{
  "Tailbreeze": {
    "AutoInstallCli": true,
    "CliDownloadUrl": "https://internal-mirror.example.com/tailwindcss-{os}-{arch}{extension}"
  }
}

// Placeholders:
// {os} = windows, macos, linux
// {arch} = x64, arm64
// {extension} = .exe (Windows) or empty

Pre-Installed CLI

Disable auto-download and use a CLI already installed on the system.

{
  "Tailbreeze": {
    "AutoInstallCli": false
  }
}

// Ensure tailwindcss is in PATH or
// installed in the project directory

# Download manually:
$ curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-windows-x64.exe

Code Configuration

Configure Tailbreeze programmatically for dynamic scenarios.

builder.Services.AddTailbreeze(options =>
{
    options.TailwindVersion = "4";
    options.EnableHotReload =
        builder.Environment.IsDevelopment();
    options.ContentPaths.Add("./Components/**/*.razor");
    options.MinifyCss =
        !builder.Environment.IsDevelopment();
});

CDN Fallback

Automatically fall back to Tailwind CDN if the CLI fails.

{
  "Tailbreeze": {
    "UseCdnFallback": true
  }
}

// If CLI fails to start or produce output,
// middleware redirects to cdn.tailwindcss.com
// Useful for development resilience

Enterprise-Ready

Version 1.1 adds resilience patterns, health monitoring, and production-grade error handling.

Resilience Patterns

Built with Polly for retry policies, exponential backoff, and circuit breaker patterns. Downloads survive transient network failures.

// Automatic retry with exponential backoff
// Circuit breaker prevents cascade failures
// File size validation after download

Health Checks

Integrate with ASP.NET Core health checks to monitor CLI availability and CSS compilation status in production.

builder
.AddTailbreezeHealthChecks();
// /health endpoint shows CLI status

Dynamic Version Fetching

Uses GitHub API to fetch latest Tailwind versions. Results cached for 15 minutes. Supports pinning to specific versions.

"TailwindVersion"
: "latest" // v4 stable
"TailwindVersion": "3" // v3.4.17 LTS
"TailwindVersion": "4.0.0" // Pinned

Full Framework Support

📄
Razor Pages
Full support
🎯
MVC
Full support
🔥
Blazor Server
Full support
🌐
Blazor WASM
Via Tailbreeze.Build
.NET 8.0
.NET 9.0
.NET 10.0
Windows x64
macOS x64/arm64
Linux x64/arm64

Ready to Add Tailwind CSS?

Get started with Tailbreeze today. Zero configuration, no Node.js, just beautiful Tailwind CSS in your ASP.NET Core app.

dotnet add package Tailbreeze
dotnet add package Tailbreeze.Build