more info ⬇


SW engineering, engineering management and the business of software

subscribe for more
stuff like this:

2020 09 19

Plain old HTML Tailwind CSS projects

Tailwind has quickly become my favorite CSS framework. One quirk of working with tailwind is that the core framework is massive. You need a proper npm or yarn setup and tree shaking via purgeCSS is necessary for any kind of production usage. You can see some numbers at the end of this post, but spoiler: 3 orders of magnitude reduction in CSS size is normal and necessary to get your CSS file to a reasonable size.

Tailwind is fantastic when paired with front end app frameworks such as Vue, React, etc. I don’t always need a front-end app framework however and simple html works fine for certain work.

It turns out that this is just a little fiddly and you can quite easily make “plain old html” projects work just fine with Tailwind.

Here’s how I do it:

Starting From Scratch

First, some basic setup:

mkdir -p site/static/css

site is where our plan old html will live. site/static is a great place for images, css and other files that don’t change.

Conceptually, site doesn’t even have to be even in the project directory, if you make the necessary adjustments to the appropriate config files.

npm init
npm install --save-dev tailwindcss
npm install --save-dev cssnano
npm install --save-dev @fullhuman/postcss-purgecss 
npm install postcss-cli --global

Next, you need a basic input.css file.

Create this at the root of your project directory (where you ran npm init).

touch site/static/css/input.css

It should contain the following three lines:

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

Basic Config

You need a few config files. What’s a modern frontend project these days without a mountain of config?

I use two different postcss config files depending on whether I want to minify or not.

mkdir build debug
touch /build/postcss.config.js
touch /debug/postcss.config.js

/build/postcss.config.js should contain the following:

module.exports = {
  plugins: [
    // ...

/debug/postcss.config.js is the same, but remove the require('cssnano') line

touch tailwind.config.js

tailwind.config.js should contain the following:

module.exports = {
  purge: {
    enabled: true,
    content: [
  theme: {
    extend: {},
  variants: {},

Lastly, open up package.json and add the following scripts:

"scripts": {
    "debug": "postcss style.css --verbose --dir ../assets/static/css",
    "build": "postcss style.css --config minify --ext min.css --dir ../assets/static/css"

You can do either of the following to generate CSS:

npm run debug   # generate, purge, but don't minify
npm run build   # generate, purge, minify

Purging can sometimes be finicky and I don’t recommend you turn it off, even in during dev or debug mode.

At this point, any html files you add to the site directory should be scanned during the purgeCSS processing.

Your style.css file should contain only relevant tailwind CSS classes.

A quick size check, using a minimal hello world HTML file:

Plain Old HTML

I love POH for simple pages. It’s rarely worth the effort to setup an entire vue or react project for something like a landing page or placeholder work. For me, it’s almost always worth the effort to get tailwind in place.

you should follow me on twitter at twitter/amattn and on at

you may also be interested in some of the greatest hits of

〜 The Sublime Developer Efficiency of Elixir, Phoenix and LiveView

〜 The Business Case For LiveView Is Strong Enough To Change How You Staff Your Dev Team

〜 Empathy as a Core Engineering Requirement

〜 Venture Capital Math 101

〜 What is Engineering Management?

the fine print:
aboutarchivetwittertwitchconsulting or speaking inquiries
© matt nunogawa 2010 - 2021 / all rights reserved
back ⬆