In Rails 8, many developers run into an annoying issue: Tailwind CSS changes don’t reflect while coding. In this post, I’ll walk you through what went wrong and how I fixed it in my project.

💡 How Tailwind is Integrated in Rails

There are couple of libraries of Ruby which helps you to include it in your project easily if your projects are Rails 7+.

  • Rails 7 comes by default with tailwindcss-rails. It does not use Node.js and instead compiles Tailwind via Ruby using tailwindcss-rails, which wraps the Tailwind CLI.
  • On the other hand, Rails 8 does not use tailwindcss-rails, by default, it comes with cssbundling-rails. But under the hood, this now uses Node.js + PostCSS via cssbundling-rails, not the tailwindcss-rails gem.

It’s more flexible and modern.

🕵️ What we will debug

Our tech stack is a Rails 8 project, but we are not using cssbundling-rails. The project has the codebase which migrated from Rails 7. So, cssbundling-rails are not part of this. We have the tailwindcss-rails.

CSS not refreshing? Things to check

✅ Tailwind build watcher running?

Many of us are running rails server(old school) or rails s
But if you use the mentioned library, it uses the Tailwind CLI under the hood. Run this to start the watcher:

bin/dev

The content of dev executable

Image description

You can see, it is silently installing foreman in your system. foreman is a manager for Procfile based applications. It expects a Procfile.dev

Image description

This tells you different commands you want to run simultaneously from a single terminal.

So when you start a bin/dev, something will look like this

Image description

✅ Tip: If you don't have bin/dev, generate it:

bundle exec rails generate tailwindcss:install

Check if Tailwind stylesheet is loaded in the layout

Ensure your layout includes the correct stylesheet:

<%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %>

Do not forget to Restart the Rails server and clear cache

Sometimes changes don’t take effect due to caching. Try:

bin/dev # or restart Puma/Webrick
rails tmp:clear

I also run rails assets:clobber to be in safer side.

🧩 tailwind.css - is it included in your layout ?

Check if the file is getting generated and modified when you update your CSS. By default, Tailwind builds output to app/assets/builds/tailwind.css. If that file isn't being updated when you change your Tailwind styles, the CLI might not be running.

Another issue found, we are using SCSS

✅ Tailwind’s watcher only watches .css files, not .scss
When you're using Tailwind CLI (e.g., via tailwindcss-rails or cssbundling-rails), it does not process or watch SCSS files like .scss or .sass.

Tailwind CLI only understands plain CSS with these special directives:

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

It doesn’t know how to compile SCSS → CSS.

Tailwind also recommends using CSS variables and stick with Tailwind-only solution.
But if you really need SCSS, we have to process this file to convert to CSS so that tailwind can understand. We need some tool like Saas (Syntactically Awesome Stylesheet).

We have the C/C++ implementation of this SaaS compiler.
There is a ruby library sassc-rails to rescue us.

so our manifest will be simpler under app/assets/stylesheets/application.scss

/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *
 *= require_tree .
 *= require_self
 */

We will have the file app/assets/stylesheets/application.tailwind.css, which contains

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

And the SCSS files we can keep under the app/assets/stylesheets.

At last, please check the configuration file under config/tailwind.config.js:

const defaultTheme = require('tailwindcss/defaultTheme')

module.exports = {
  content: [
    './public/*.html',
    './app/helpers/**/*.rb',
    './app/javascript/**/*.js',
    './app/views/**/*.{erb,haml,html,slim}',
    './app/assets/stylesheets/**/*.{css,scss}'
  ],
  theme: {
    extend: {
      fontFamily: {
        sans: ['Inter var', ...defaultTheme.fontFamily.sans],
      },
    },
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('@tailwindcss/aspect-ratio'),
    require('@tailwindcss/typography'),
    require('@tailwindcss/container-queries'),
  ]
}

Now the testing time, start your application by bin/dev, puma got activated, Tailwind cli got activated.

Update a CSS file, reload the browser, and hopefully the update will be shown in the browser. 💥

🔆 Conclusion

Rails + Tailwind is now a days a trendy combo. Before using you need to know which integration method you’re using (tailwindcss-rails vs cssbundling-rails). If you’re using the Tailwind CLI via Ruby, just make sure the watcher is running, your styles are properly linked, and SCSS is being compiled correctly.
Happy coding!!