iTranslated by AI
[C#] Using Tailwind CSS in Blazor the Easy Way
I'm going to use Tailwind CSS with Blazor.
What is Tailwind CSS
It is a CSS framework.
While there are many such frameworks, its defining characteristic is the "Utility-First" philosophy.
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Button
</button>
As shown above, it's a style where you specify classes in great detail.
Looking at this alone, it seems like a lot of work, and you might wonder how it differs from writing styles directly (inline styles). However, a wide variety of utility classes are provided, and by combining them, you can flexibly adjust the design.
Additionally, responsive designs like "if dark mode, then XX" or "if width is below XXpx, then YY" can be easily implemented.
(In the example above, hover:bg-blue-700 specifies the background color on hover!)
Using it in Blazor
Now, when you actually try to use it and look it up, you'll see steps like:
- Install Node.js
- Install tailwindcss/postcss via npm
- Configure postcss
- Create tailwind.config.js
- Run a separate watch process on top of that...
These are the steps that often come up. Since misconceptions might spread if no one corrects them, let me state it clearly here.
You don't need the steps above!
To get straight to the point, you can use Tailwind CSS in Blazor just as easily as you would with Node.js development.
Misconception 1: Node.js/npm is Required
First, since Tailwind CSS consists of a massive amount of utility classes, the CSS file would become extremely large if it included all of them.
While a "full" version is provided via CDN, it is strictly for development purposes. For actual use, it is common to go through a build process to include only the necessary classes.
The method that comes up first when searching is using postcss. Looking at this alone, it seems like Node.js/npm is required.
However! In fact, an official CLI tool is provided, and by using this, Node.js/postcss becomes unnecessary. (Under the hood, it's a Node.js application packaged into an executable using pkg, but it is designed to run independently as a standalone CLI.)
Misconception 2: tailwind.config.js is Required
The latest version of Tailwind CSS is v4 (as of October 2025), and the configuration method has changed significantly from v3.
Perhaps the official team also felt that using a JS file for a CSS framework's configuration was a bit odd; starting from v4, configuration is now basically written directly in the CSS file.
There are many specific examples, so I will omit them here, but when searching for configuration methods, I recommend searching for "Tailwind CSS v4".
You can generally assume that anything mentioning tailwind.config.js is outdated.
Misconception 3: You need to install the CLI and add it to your path, or run it separately
In a sense, this is correct[1], but you can also have it handled automatically. While several options appear on NuGet, in my experience, Tailwind.Hosting is the easiest to use.
You don't need to install the CLI or set up your path; just add the PackageReference to your project and prepare an input CSS file (the package will automatically download and use the CLI for you).
To summarize the above
- Node.js/npm is not required.
-
tailwind.config.jsis not required. - No need to manually install the CLI if you use a dedicated NuGet package.
- It can be integrated into the C# build process for automatic generation.
Wonderful!
Putting it into Practice
So, let's try it out.
First, we introduce the aforementioned Tailwind.Hosting. We also specify the path for the configuration file tailwind.css.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<!-- omitted -->
</PropertyGroup>
<!-- tailwind setting -->
<ItemGroup>
<PackageReference Include="Tailwind.Hosting" Version="*" />
<PackageReference Include="Tailwind.Hosting.Build" Version="*" />
</ItemGroup>
<PropertyGroup Label="Tailwind.Hosting.Build Props">
<TailwindVersion>latest</TailwindVersion>
<TailwindWatch>true</TailwindWatch>
<TailwindInputCssFile>tailwind.css</TailwindInputCssFile>
<TailwindOutputCssFile>wwwroot/app.css</TailwindOutputCssFile>
</PropertyGroup>
<!-- Required for Windows / .NET 9 or later -->
<Target Name="CleanUpTailwindStaticCache" BeforeTargets="PrepareForBuild" Condition="'$(OS)' == 'Windows_NT'">
<ItemGroup>
<Content Remove="$(TailwindOutputCssFile)" />
</ItemGroup>
</Target>
</Project>
Next, prepare the input CSS file.
/* tailwind.css */
@import "tailwindcss";
Now, all that's left is to use it in a component.
@page "/"
<PageTitle>Home</PageTitle>
<div class="flex h-dvh flex-col items-center justify-center">
<h1 class="p-2 font-bold text-5xl">Hello, world!</h1>
<p>Welcome to your new app.</p>
</div>
Finally, let's build it.
Then, wwwroot/app.css is generated, and the styles are applied as shown below!

Looking at the output CSS file, you can see that only the necessary classes are included.
/*! tailwindcss v4.1.14 | MIT License | https://tailwindcss.com */
/* omitted */
@layer utilities {
.visible {
visibility: visible;
}
.static {
position: static;
}
.flex {
display: flex;
}
.h-dvh {
height: 100dvh;
}
.flex-col {
flex-direction: column;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.p-2 {
padding: calc(var(--spacing) * 2);
}
.text-5xl {
font-size: var(--text-5xl);
line-height: var(--tw-leading, var(--text-5xl--line-height));
}
.font-bold {
--tw-font-weight: var(--font-weight-bold);
font-weight: var(--font-weight-bold);
}
}
/* omitted below */
Adding Editor Support
Tailwind has a vast number of classes, so having autocompletion in your editor is extremely convenient (or rather, it's painful without it!).
Fortunately, there is an extension for Visual Studio, so let's try installing it.
After installing it, if you try editing a class attribute...

Autocompletion now works! This should make development much more comfortable.
If it bothers you that the extension also runs a build, it's a good idea to set the Build Type to None in the options.

Using a CDN Only During Development
Up to this point, we have been able to generate an optimized CSS file using Tailwind CSS during the build. However, in practice, there are times when you want to quickly tweak class names in the DevTools to verify the display.
In such cases, the pre-built CSS does not include all classes, so it may not be reflected correctly, which is inconvenient.
While Tailwind.Hosting mentions a way to monitor with "watch," I found that it didn't work for me, and I was concerned that it only works with dotnet watch.
So, I tried using the CDN only during development. Simply create a component like the following and add it to App.razor or elsewhere.
@TAILWIND_CDN_FRAGMENT
@code {
#if DEBUG
private static RenderFragment? TAILWIND_CDN_FRAGMENT = @<script src="@TAILWIND_CDN_URL"></script>;
private const string TAILWIND_CDN_URL = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4";
#else
private static RenderFragment? TAILWIND_CDN_FRAGMENT = null;
#endif
}
With this, even when editing in DevTools, changes will be automatically reflected (only during development).
Handy Tips
Using in a Proxy Environment
In some cases, you may encounter a 407 Proxy Authentication Required error.
In that case, set the HTTPS_PROXY environment variable and run dotnet build from the CLI. Once you have completed this step for the first time, it will use the downloaded CLI for subsequent builds.
Adding a Prefix
If you are already using a UI framework in Blazor and want to introduce Tailwind CSS supplementally, there is a possibility that class names might conflict. In such cases, you can add a prefix to Tailwind CSS classes.
Simply update your tailwind.css (input file) as follows:
@import "tailwindcss" prefix("tw");
After that, you can specify classes by adding tw:. The previous example would look like this:
<div class="tw:flex tw:h-dvh tw:flex-col tw:items-center tw:justify-center">
<h1 class="tw:p-2 tw:font-bold tw:text-5xl">Hello, world!</h1>
<p>Welcome to your new app.</p>
</div>
As you can see, it's a bit tedious, so it's easier not to use one.
Summary
I have introduced how to use Tailwind CSS in Blazor. It's surprisingly easy to set up, so I plan to continue using it in the future.
Update History
2025/10/22:
Changed to the method using Tailwind.Hosting. I stopped using mvdmio.Tailwind.NET, which I previously introduced, because it required Node.js and did not match the premise of this article.
2025/11/30:
Updated the description for CleanUpTailwindStaticCache. Added the method for using a CDN only during development.
-
That approach is more flexible—for things like watching files or running in CI. ↩︎
Discussion