Tailwind JIT and Hugo Purge issues

Tailwind just released their new JIT compiler which looks super useful for creating small stylesheets during development.

I’m currently using Tailwind on my Hugo site and in the process of trying to setup Tailwind JIT I couldn’t get it to work. My current setup is purging CSS styles using the Hugo stats file.

When I tried to purge the CSS using the tailwind.config.js file, my site would never start up when I run hugo serve, it would just hang at Starting site.

Has anyone been able to set this up with Hugo?

1 Like

So the new JIT Tailwind compiler replaces the need for purging, so that’s one issue. The Hugo stats file is not created until build time, so that will not update realtime. I’d imagine that you would need two terminals running at the same time, one for hugo and one for the JIT compiler.

Right that makes sense. Even still I had issues with running Hugo when trying to do the purge without the hugo stats file and instead using the purge settings from tailwind.config.js

It’s possible this could be a Tailwind issue and not necessarily a Hugo issue but wanted to post here in case anyone else was trying the same setup with Hugo

Yeah, so I specify purge settings inside postcss.config.js instead of inside the tailwind.config.js file. I have the post css config point to the hugo stats file. The idea is that Hugo runs the post css process instead of relying on the tailwind plugin to do it.

Here is my postcss.config.js which I have in assets/css/ at my project root

const themeDir = __dirname + "/../../";

const purgecss = require("@fullhuman/postcss-purgecss")({
  // Specify the paths to all of the template files in your project
  content: ["./hugo_stats.json"],

  // This is the function used to extract class names from your templates
  defaultExtractor: (content) => {
    // Capture as liberally as possible, including things like `h-(screen-1.5)`
    const broadMatches = content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [];

    // Capture classes within other delimiters like .block(class="w-1/2") in Pug
    const innerMatches = content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || [];

    return broadMatches.concat(innerMatches);

module.exports = {
  plugins: [
      path: [themeDir],
    require("tailwindcss")(themeDir + "assets/css/tailwind.config.js"),
      path: [themeDir],
    ...(process.env.HUGO_ENVIRONMENT === "production" ? [purgecss] : []),

I will find some time to test this, but as I understand it:

  • The JIT compiler is a development thing, so you would somehow have different setups for dev and production
  • There is another thread that mentions this currently failing with Hugo

One of the pros of tailwind jit is that it unifies development and production build processes. It’s still beta, so some people might not be comfortable with using it in production, but its readme explicitly mentions that its designed to be used for both environments.

An option to enable writeStats in server mode would be nice to have to enable this.

1 Like

I have a plan to make TailwindJIT work great with Hugo. I tested it last night (I have a ongoing branch on GitHub), and the current main missing piece is a way to use JIT’s incremental builds. I have an idea which I think will work.


@bep were you able to make any progress on this?

@mhal see Tailwind v3.0 and Hugo

1 Like

okay, thank you. seems there is no perfect solution for this yet.

My 3.0 test repo works fine and so far I did not came across any issue. I ported one existing site (that had Tailwind 2.2.* before), no problems found. Purged and minified fingerprinted CSS get’s generated just fine.