DEV Community

Cover image for Middleman + TailwindCSS + Webpack

Middleman + TailwindCSS + Webpack

lxxxvi profile image Mario Updated on ・4 min read

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
Enter fullscreen mode Exit fullscreen mode

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.

  1. Add gem 'middleman-livereload' to ./Gemfile
  2. Add activate :livereload to ./config.rb
  3. 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
Enter fullscreen mode Exit fullscreen mode

(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
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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: [
Enter fullscreen mode Exit fullscreen mode

(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',
Enter fullscreen mode Exit fullscreen mode

While I created this file I made several observations that I'd like to share:

  • The keys in entry: { ... } (application and styles) will be used as filenames. So there will be a file named application.js and one named styles.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.path apparently has to be /.tmp/dist (!), otherwise Middleman won't use it in development?
  • Lastly, the rule for .css files is more or less copy/pasted from MiniCssExtractPlugin project page. I assume this plugin is responsible for processing/creating a styles.css file in the output path? Note that this plugin replaces a plugin named extract-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
Enter fullscreen mode Exit fullscreen mode

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" %>
Enter fullscreen mode Exit fullscreen mode


<%= stylesheet_link_tag "styles" %>
<%= javascript_include_tag "application" %>
Enter fullscreen mode Exit fullscreen mode

Moment of truth...


middleman serve
Enter fullscreen mode Exit fullscreen mode

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.


Cover image by Marco Verch

Discussion (6)

Editor guide
godsloveady profile image
Derrick Amenuve

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

rolandstuder profile image
Roland Studer

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:

    @tailwind base;
    @tailwind components;
    @tailwind utilities;

    body {
        @apply bg-red-500;
lxxxvi profile image
Mario Author

Hi Roland

Thank you for your input!

In Tailwind's current Installation guide, it says

"If you're using postcss-import (or a tool that uses it under the hood, such as Webpacker for Rails), use our imports instead of the @tailwind directive to avoid issues when importing any of your own additional files:"

@import "tailwindcss/base";

@import "tailwindcss/components";

@import "tailwindcss/utilities";

My guide uses postcss-import so I assume these directives should be OK?

claudiovallejo profile image
Claudio Vallejo

Mario thanks for writing this post. It was very easy to follow and setup! In the "Prepare CSS file" section, styles.css should use @import instead of @tailwind.

lxxxvi profile image
Mario Author

Thank you very much, I changed it.

allanwhite profile image
Allan White

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.