Tailwind version 4 was just released. With the new CLI, it is just so much easier to use tailwindcss with Blazor. So in this post, I will show you how to use the new CLI to create a new Blazor project with Tailwind v4.
Short disclaimer: If you still want to use version 3, I already wrote an article about this some time ago: "Blazor with TailwindCSS".
tailwind/cli
The basic installation setup is taken from the official documentation: https://tailwindcss.com/docs/installation/tailwind-cli I will link the sample repository at the end of this post so you can see the full setup.
But here the short gist:
- Create a new Blazor project You can either use your favorite IDE or the dotnet CLI to create a new Blazor project. I will use the dotnet CLI for this example:
dotnet new blazor -o BlazorTailwind
- Install the cli with tailwind:
npm install tailwindcss @tailwindcss/cli
This will create a package.json (and package-lock.json) file and a node_modules folder. Therefore I would recommend adding the node_modules folder to your .gitignore file. The package.json looks like this:
{
"dependencies": {
"@tailwindcss/cli": "^4.0.8",
"tailwindcss": "^4.0.8"
}
}
- Use tailwind
Inside your wwwroot/app.css add tailwind like this on the first line:
@import "tailwindcss";
- Generate the merged css file
We are almost done. The last step is to generate the generated CSS file which consists of all the tailwind classes and your custom definitions in your wwwroot/app.css file. You can do this by running the following command:
npx @tailwindcss/cli -i wwwroot/app.css -o wwwroot/dist.css
This will generate a dist.css file in your wwwroot folder. You can now include this file in your App.razor instead of the app.css file like this:
<!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="dist.css"/>
<link rel="stylesheet" href="@Assets["BlazorTailwind4.styles.css"]"/>
Now let's go to our Home.razor, use some tailwind classes and run the npx command again:
<h1 class="p-4 font-bold text-blue-600">Hello, world!</h1>
Will result in:

Now you might have seen, that I did not use the @Assets directive. And there is a reason. The process I showed is very manual and you have to run the command every time you change something in your app.css file. But there is a better way to do this.
Automate the process
We can use the npx command to get executed everytime we build the project. For that let's go to our package.json:
{
"dependencies": {
"@tailwindcss/cli": "^4.0.8",
"tailwindcss": "^4.0.8"
},
"scripts": {
"build:css": "npx @tailwindcss/cli -i wwwroot/app.css -o wwwroot/dist.css"
}
}
With scripts we can execute commands. So we can now run build:css everytime we build. To do that, just add the following line to your .csproj file:
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="npm run build:css" />
</Target>
Now everytime you build your project, the dist.css file will be generated. That said, you might want to gitignore the dist.css file, because it will be generated everytime you build the project anyway. No need to keep the autogenerated file in your repository.
GitHub Actions
The unfortunate thing is, that you have to have node installed on your machine or your GitHub action. So to make a minimal CI pipeline work, you want to have something like this:
name: Build
on:
push:
branches:
- main
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm install
- name: Set up .NET Core
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.x'
- name: Build with dotnet
run: dotnet build --configuration Release
dotnet watch
If you are like me, you are using dotnet watch aka hot-reload all the time. But there is an inherit problem with tailwindcss and the stuff we built up earlier. dotnet watch does not invoke the pre-build event. So to come around that fact you basically need two shells open. The first one for your dotnet watch and the second to let tailwind watch your code:
npx @tailwindcss/cli -i wwwroot/app.css -o wwwroot/dist.css --watch
Now tailwind automatically recognizes changes in your app.css file and updates the dist.css file. Of course you can also park that in your package.json:
{
"dependencies": {
"@tailwindcss/cli": "^4.0.8",
"tailwindcss": "^4.0.8"
},
"scripts": {
"build:css": "npx @tailwindcss/cli -i wwwroot/app.css -o wwwroot/dist.css",
"watch:css": "npx @tailwindcss/cli -i wwwroot/app.css -o wwwroot/dist.css --watch"
}
}
And just call npm run watch:css