Rails 6, TailwindCSS, TailwindUI, and Stimulus New App Guide (November 2020)

Making Nov 29, 2020

Changes

  • Sunday, November 29 2020: Updated for TailwindCSS 2.x PostCSS 7 compatibility.

Starting your new Rails 6 app

Getting started on a new Rails 6.x app and want the latest TailwindCSS, Webpack, and Stimulus as your base development stack?

Look no further! This article is all you need.

I'll keep updating it over the course of the next couple of weeks as a few compatibility issues will be resolved.

Installation and generator commands are included below. As well as Tailwind configuration files you need to add or modify for Rails specifically. I've also included references to any upstream documentation.

Let's get started.

Installing Rails 6.x

At the time of writing the latest Rails release is 6.0.3.4 and latest RC is 6.1.0.rc1.

Install or update your local Rails gem with:

$ gem install rails

Generating the Rails app with Webpack, Stimulus, and PostgreSQL

Here's the Rails app generator command I use:

$ rails new mynewapp --database=postgresql --webpack=stimulus
$ cd mynewapp

Yarn add TailwindCSS with a PostCSS compatibility fix

First, add TailwindCSS to your Rails app via Yarn (and not via npm). You will be installing TailwindCSS as a PostCSS Plugin because that's how you do JavaScript libraries in Rails.

In addition, you need install a TailwindCSS compatibility build that works with PostCSS 7. As Rails is not on the required PostCSS 8 yet.

Run the following command and select 2.0.1-compat as the version to install.

$ yarn add tailwindcss@comp
yarn add v1.22.4
info No lockfile found.
[1/4] 🔍  Resolving packages...
Couldn't find any versions for "tailwindcss" that matches "comp"
? Please choose a version of "tailwindcss" from this list: 
  2.0.1 
❯ 2.0.1-compat 
  2.0.0 
  2.0.0-compat

Add TailwindCSS to PostCSS config

Edit the generated postcss.config.js in your Rails app and add the tailwindcss and autoprefixer requires. You'll add a configuration parameter to the tailwindcss require to tell TailwindCSS where to look for its configuration file.

module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss')('./app/javascript/tailwind.config.js'),
    require('autoprefixer'),
    require('postcss-flexbugs-fixes'),
    require('postcss-preset-env')({
      autoprefixer: {
        flexbox: 'no-2009'
      },
      stage: 3
    })
  ]
}
postcss.config.js

Create the TailwindCSS config file with Inter font and Forms plugin

Create the tailwind.config.js configuration file in app/javascripts and set it to use the Inter font as recommended in the Tailwind UI documentation. I've also added in the @tailwindcss/forms:

const defaultTheme = require('tailwindcss/defaultTheme')

module.exports = {
  purge: [],
  darkMode: false, // or 'media' or 'class'
  variants: {},
  plugins: [
    require('@tailwindcss/forms'),
  ],
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter var', ...defaultTheme.fontFamily.sans],
      },
    },
  }
}
app/javascript/tailwind.config.js

Add TailwindCSS Forms plugin with Yarn

At this stage your bin/webpack-dev-server won't start unless you add the tailwindcss/forms plugin to your app:

$ yarn add @tailwindcss/forms

Add TailwindCSS imports to your JavaScript pack

This article uses the setup where we combine the Javascript and CSS of the app into one pack. So we will include the TailwindCSS import directive directly into the top-level app/packs/application.js file:

// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)

import "controllers"

import "tailwindcss/tailwind.css"
app/javascript/packs/application.js

Update your application layout's CSS include for a combined JavaScript/CSS Pack

Rename the stylesheet_link_tag to stylesheet_pack_tag in your application.html.erb to make sure your CSS is loaded in.

<!DOCTYPE html>
<html>
  <head>
    <title>Mynewapp</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
app/views/layouts/application.html.erb

Create and migrate your initial database

The app we generated at the start of this article uses a PostgreSQL database. Run the initial database creation and migration to get started!

$ bin/rails db:create
$ bin/rails db:migrate

That's it! Please definitely let me know if you've used this article. And also if you're experiencing any troubles — I can add a troubleshooting section then.

You can reach me on Twitter or via email at michiel [at] hey [dot] com.

See you in the next one.

— Michiel

Tags

Michiel Sikkes

I'm the co-founder and CTO at Firmhouse, a software platform to run Product as a Service and Hardware as a Service business models.

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.