Posted on November 30, 2020 | Guille

A blog is as simple as it gets in terms of websites, yet by using modern tools such as React and Bootstrap to build it you are essentially adding an overhead that is several times the size of the actual content. Since page download and rendering times are critical for the success of your blog from both a UX and SEO point of view, this is just unacceptable. Thanks to Hugo and Tailwind CSS you can produce the bare minimum needed for a beautiful site, and maintain it easily.

What is Hugo?

Hugo is a Static Site Generator (SSG): a tool that produces websites that are composed of only static pre-built files (basically html, js, and css), instead of having a web server create these files dynamically. You could write these files from scratch yourself, but Hugo let’s you prepare some templates and define content in Markdown and then puts it all together, which is much more handy.

What is Tailwind CSS

Tailwind CSS is a utility-first CSS framework. That means that instead of trying to give semantic class names to the elements of your site and then define the styles for those elements in CSS, you use style class names directly like pt-4 for padding-top: 1rem, or text-center for text-align: center. This simplifies design building because you can see what is happening directly in the HTML and don’t have to come up with names for each element. Also, since it works as a PostCSS plugin, the resulting CSS file includes only the classes that you have used.

Setting up Hugo with Tailwind CSS

Since version 0.43 Hugo has something called Hugo Pipes which allows processing assets, including CSS files with PostCSS. Therefore, setting up Tailwind CSS with Hugo is fairly straightforward: just install the necessary dependencies, configure PostCSS, and add the template code to process the css asset into the final css static file. Hugo uses the command-line version of PostCSS, so you’ll need postcss-cli. The Tailwind CSS PostCSS plugin is in the talwindcss package. You’ll also need the autoprefixer plugin to automatically add vendor prefixes, and postcss, which is a peer dependency of all the previous packages. So you’d run:

npm install postcss postcss-cli tailwindcss autoprefixer

To configure PostCSS with these plugins you need a postcss.config.js file:

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},

Tailwind CSS also has a configuration file tailwind.config.js that should be initialized as:

module.exports = {
  purge: {
    enabled: true,
    content: ["./layouts/**/*.html"]
  darkMode: false,
  theme: {
    extend: {},
  variants: {},
  plugins: [],

The purge content array tells PostCSS where to look for classes that are being used and therefore will be kept in the final generated CSS file. It should include all the files where you are using Tailwind CSS classes: if using a theme made with Tailwind CSS you would want to add its directory as well, and if you have html content then the content directory would also need to be included.

The last step is to add the PostCSS processing to the Hugo layout corresponding to the head of your site:

{{ $styles := resources.Get "css/main.css" }}
{{ $styles = $styles | resources.PostCSS (dict "inlineImports" true) }}
{{ $styles = $styles | minify }}
<link rel="stylesheet" href="{{ $styles.Permalink }}">

And with that you can have a blog that looks great with only minimal CSS.