If you’ve been following along with our previous posts about WebStencils, you know we really value making modern web development easier for RAD Studio developers. Today, we want to share something we’ve been working on: integrating Tailwind CSS with Delphi projects in a way that’s actually practical and doesn’t require jumping through hoops.
The Main Idea
The challenge with modern CSS frameworks like Tailwind CSS is that they typically require Node.js and a build toolchain. But what if we could use Tailwind’s standalone CLI binary instead? And what if we could set up a workflow where development is fast (using a CDN) and production is optimized (using a generated CSS file), all without ever touching npm or package.json?
That’s exactly what we’ve done. We’ve created a demo project that shows how to integrate Tailwind CSS with Delphi using WebStencils and WebBroker, with a hybrid approach that switches between CDN and local CSS based on your build configuration. The best part? It’s all automated through Delphi’s post-build events, so you don’t have to think about it.
What is Tailwind CSS?
Before we get into the how, let’s quickly explain what Tailwind CSS is and why it works the way it does.
Tailwind CSS is a utility-first CSS framework. Instead of writing custom CSS or using pre-built components, you compose your UI by applying small utility classes directly in your HTML. For example, instead of writing:
[crayon-69447acebb6f1867688762/]You’d write:
[crayon-69447acebb6f6422668933/]This approach is great for rapid development, but there’s a catch: Tailwind generates thousands of utility classes, and if you include all of them, your CSS file would be massive (think 3-4MB). That’s why projects that use Tailwind CSS need to be “built” to include only the classes used in the HTML.
Now, I should mention that Tailwind CSS is somewhat divisive. Some developers love it for the granular control it offers because you can fine-tune every aspect of your design without writing custom CSS. Others find the resulting HTML cluttered and hard to read with all those utility classes. I’m not here to pick a side. The point of this post is to show that if you want to use Tailwind with Delphi, you can, and it doesn’t have to be complicated.
This is actually one of the things I love about WebStencils: it’s completely agnostic about CSS and JavaScript. You’re not locked into any particular framework or approach. Want to use Tailwind? Go for it. Prefer Bootstrap? That works too. Want to write custom CSS? Absolutely fine. WebStencils just renders your templates, what you put in them is entirely up to you.
The Build Process
Tailwind uses a build process that scans your HTML templates, finds which classes you’re actually using, and generates a CSS file containing only those classes. This process (often called “content scanning” or “tree-shaking”) means instead of a 3-4MB CSS file, you get something like 5-50KB with only the styles you need.
Traditionally, this build process requires:
- Node.js installed on your machine
- npm (Node Package Manager)
- A build tool like Vite or Webpack
- A
package.jsonfile with dependencies - Running
npm installandnpm run buildcommands
For Delphi developers who just want to style their web apps, this is a lot of overhead. You’re essentially setting up a JavaScript development environment just to generate CSS.
The RAD Way: No Node.js Required
Here’s where things get interesting. Tailwind CSS actually provides a standalone CLI binary that doesn’t require Node.js at all. It’s a single executable file that does everything the Node.js version does, just without the npm ecosystem.
So the workflow becomes much simpler:
- Download the standalone CLI – Just grab the latest
tailwindcss-windows-x64.exefrom GitHub releases - Configure a post-build event – Tell Delphi to run the CLI after building in Release mode (more details later)
- That’s it – The CSS gets generated automatically
But there’s more. For development, you don’t even need to run the build process. You can use Tailwind’s CDN, which includes all classes. This means:
- Debug builds: Use CDN, no build step, instant changes with all Tailwind classes available
- Release builds: Generate optimized CSS file automatically via post-build event with only the classes you’ve used
The application itself detects which mode it’s in and loads the appropriate CSS source.
How It Works
The magic happens in the baseLayout.html template. Using WebStencils’ conditional syntax, we check if we’re in debug mode:
The env.debug variable is set in Delphi code based on {$IFDEF DEBUG}, so the template automatically knows which CSS to load.
When you build in Release mode, Delphi’s post-build event runs:
[crayon-69447acebb6f9749960067/]This command:
- Takes
src/input.cssas input - Scans all HTML files in the
templates/directory - Generates an optimized, minified CSS file with only the classes you’re using
- Outputs it to
templates/static/css/output.css
Two small files make this work: src/input.css just imports Tailwind (@import "tailwindcss";) so the CLI knows what to generate, and tools/tailwind.config.js tells Tailwind where to look for classes (in this case templates/**.html). Even lets you safelist any dynamic classes you could generate in Delphi. You normally won’t touch these often, but you can customize them per project if needed, and Tailwind’s docs cover the options in depth.
Try it yourself
If you want to see this in action, check out the demo project on GitHub. The README has all the setup instructions. The only thing you need to do is download the Tailwind CLI binary, rename it to tailwindcss.exe and place it in the tools/ directory, everything else is already configured.
The project demonstrates that Delphi can work with modern CSS frameworks without requiring you to become a JavaScript developer. Sometimes the best solution is the simplest one, and in this case, that means using the standalone CLI and letting Delphi’s build system handle the rest.
What do you think? Have you tried using modern CSS frameworks with Delphi? I’d love to hear about your experiences and any other approaches you’ve taken.

