I really enjoy using Middleman for some websites that I maintain. For one of my projects I wanted to include TailwindCSS and started googling how to do that. I found this guide but it seemed bit outdated.
This got me inspired to write an updated version.
So, in this guide I'm trying to describe how I managed setting up a middleman project and integrate TailwindCSS using Webpack.
It uses these versions:
- Middleman
4.3.4 - Tailwind
1.0.4 - Webpack
4.35.2
Disclaimer: I am not an expert with Webpack etc. So the following instructions may be inaccurate, incomplete or misleading. I hope it's not too bad though, please comment if you feel something is terribly wrong.
Here we go...
Setup a Middleman project
Firstly, install Middleman and create a project
gem install middleman
middleman init project
cd ./project
middleman serve
Once middleman serve is running you should see a default page on http://localhost:4567. You may abort the process again since we're going to change some configurations now...
Also, from now on this guide assumes that the working directory is the project's root directory.
(These instructions were taken from the Middleman installation page)
Add Livereload (Optional)
Livereload automatically reloads the page in the browser every time we change something in the code, which can be useful later.
- Add
gem 'middleman-livereload'to./Gemfile - Add
activate :livereloadto./config.rb - Run
bundle install
(These instructions were taken from the Middleman Basics page)
Add npm packages
Now we get to the first part where I don't have much knowledge about. After some experimenting I concluded this list of packages
yarn init
yarn add autoprefixer css-loader mini-css-extract-plugin postcss postcss-import postcss-loader style-loader tailwindcss webpack webpack-cli
(You may substitute yarn with npm. Use npm install instead of yarn add)
Prepare CSS file
Middleman comes with SCSS, but I decided to not use SCSS together with Tailwind. That's why I renamed the stylesheet's filename:
mv ./source/stylesheets/site.css.scss ./source/stylesheets/site.css
Then I changed the content of ./source/stylesheets/site.css to this:
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
body {
@apply bg-red-500;
}
This imports the Tailwind definitions and applies a rule to the body tag using Tailwind's @apply directive. At the end of this guide we expect the background color of the page to be red(-ish).
(This instruction was taken from the Tailwind's installation page)
Create postcss.config.js
Next we're going to create a file ./postcss.config.js with this content:
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
]
}
(This instruction was taken from the Tailwind's installation page)
Configure webpack
To me, configuring webpack was the most difficult part. There are a lot of examples for this on the interwebs and as a JS-noob I couldn't make clear which way is the best. But here's what I came up with.
Create a file ./webpack.config.js with this content:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin()
],
entry: {
application: './source/javascripts/site.js',
styles: './source/stylesheets/site.css',
},
output: {
path: __dirname + '/.tmp/dist',
filename: '[name].js',
},
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader',
'postcss-loader',
]
}
]
}
}
While I created this file I made several observations that I'd like to share:
- The keys in
entry: { ... }(applicationandstyles) will be used as filenames. So there will be a file namedapplication.jsand one namedstyles.js(yes... the styles file's extension is going to be.js, I guess it won't be used though, may be I can get rid of it somehow?) -
output.pathapparently has to be/.tmp/dist(!), otherwise Middleman won't use it in development? - Lastly, the rule for
.cssfiles is more or less copy/pasted fromMiniCssExtractPluginproject page. I assume this plugin is responsible for processing/creating astyles.cssfile in the output path? Note that this plugin replaces a plugin namedextract-text-webpack-plugin.
You see, in this area I have multiple question marks. So if you have corrections, I invite you to post them in the comments.
Activate Webpack as :external_pipeline
Now let's hook up webpack to the Middleman pipeline.
Add these lines to ./config.rb
activate :external_pipeline,
name: :webpack,
command: build? ? './node_modules/webpack/bin/webpack.js --bail' : './node_modules/webpack/bin/webpack.js --watch -d --color',
source: ".tmp/dist",
latency: 1
This ensures that webpack runs as soon as anything changes in the project during development or when we build the project.
(This instruction was taken from the Middleman Documentation)
Change stylesheet and javascript paths in ./source/layouts/layout.erb
Remember that we configured webpack so we get a file named application.js and one named styles.css as outputs? We need to change these filenames in the head section of the page.
In ./source/layouts/layout.rb change
<%= stylesheet_link_tag "site" %>
<%= javascript_include_tag "site" %>
to
<%= stylesheet_link_tag "styles" %>
<%= javascript_include_tag "application" %>
Moment of truth...
Run
middleman serve
Check whether the background of the page at http://localhost:4567 is red(-ish). If so, this guide is trustworthy and you can happily start using Tailwind in your project. If not, put the blame on me and share your experience.
Credits
Cover image by Marco Verch

Latest comments (8)
This was a super helpful article for understanding a lot of the setup. Thank you!
I've created a HOWTO for Tailwind CSS 3 and Middleman here: donnfelker.com/tailwind-css-with-m... (or just clone the code here: github.com/donnfelker/middlemanapp...)
I hope it helps someone!
Wow you should really think about reproducing your blog post into a post here on Dev. This was very helpful and most up-to-date. Thanks so much!
Please this is the error i run into after running middleman serve command. Can anyone please help?
WARN: Unresolved or ambiguous specs during Gem::Specification.reset:
minitest (~> 5.1)
Available/installed versions of this gem:
- 5.14.2
- 5.11.3
WARN: Clearing out unresolved specs. Try 'gem cleanup '
Please report a bug if this causes problems.
== The Middleman is loading
== Executing:
./node_modules/webpack/bin/webpack.js --watch -d --color== External: Command failed with message: No such file or directory - ./node_modules/webpack/bin/webpack.js
Mario thanks for writing this post. It was very easy to follow and setup! In the "Prepare CSS file" section,
styles.cssshould use@importinstead of@tailwind.Thank you very much, I changed it.
Hey, the tailwind directives in your example CSS are no longer correct. It would be great if you could update your article. With current versions of Tailwind you need to use:
Hi Roland
Thank you for your input!
In Tailwind's current Installation guide, it says
My guide uses
postcss-importso I assume these directives should be OK?Thanks so much for this walkthrough! I've used Middleman for years and getting it integrated with web pack (and in particular, Tailwind) was a real chore. Much appreciated.