---
title: Using Tailwind CSS AND Bootstrap side by side in Rails
author: Daniel Schoppmann
tags: Bootstrap, TailwindCSS, Design
published_at: '2024-01-02T17:51:00+01:00'
updated_at: '2024-01-04T10:52:57+01:00'
canonical_url: https://www.dotruby.com/articles/using-tailwind-css-and-bootstrap-side-by-side-in-rails
---

# Using Tailwind CSS AND Bootstrap side by side in Rails

Ever wondered how to use Tailwind CSS AND Bootstrap within the same Rails application? Maybe you have different parts of the app where you want to take advantage of the better suited CSS framework. It's actually pretty easy to do in Rails and our go to approach in monolithic Rails apps.

## Why using both Tailwind and Bootstrap?

Compared to a few years ago, it's a blast to develop Rails apps with modern frontend tools these days. The full JS and CSS ecosystems are first class citizens in any modern Rails app these days. Let's quickly forget the sad days of webpackers and the like.

As much as we love Rails as a framework for all business logic related coding, we also love the helping hands of CSS frameworks for our frontend work. Even though Rails 8 will even more embrace things like #nobuild, importmaps etc. we usually stick to CSS frameworks and some of their provided JS components just for simplicity. All served within the Rails app with the [`jsbundling-rails`](https://github.com/rails/jsbundling-rails) and [`cssbundling-rails`](https://github.com/rails/cssbundling-rails) gems. 

If you're like us, you've probably used both [Tailwind CSS](https://tailwindcss.com) and [Bootstrap](https://getbootstrap.com/) as well. Obviously, both frameworks have their pros and cons, but each is great for certain needs. When it comes to integrating them with Rails, it's usually described as choosing one of them in advance. So while building the app, you can decide whether to use Tailwind or Bootstrap (or any other alternative framework, of course).

However, in more monolithic Rails applications like the ones we prefer to work on, we often choose to use both Tailwind AND Bootstrap. In our case, it usually boils down to using Tailwind as a more bare bones and custom styling toolset, e.g. for all the user-facing parts of an application where you'd build your own styled components anyway. Bootstrap instead is super easy and fast with all the standard components. It's often used to build pure CRUD areas in the application that don't need a special custom look. A typical use case for this is some kind of admin area within the application.

So can we actually use *both Tailwind and Bootstrap* in the same application with the ease we expect from Rails?

Oh yes, turns out it's pretty easy to do! Even though Bootstrap is built around [sass](https://sass-lang.com/) and Tailwind uses its own compiler, as long as we pipe the build output to the right places, it just works! All we have to do is slightly tweak the build process for each of them. Follow along!

## Create a new Rails app

Let’s assume we are building something similar to the use case mentioned above: We’ll use Tailwind for our application layout (and thus call the files `application.*`) and Bootstrap for our admin layout (calling the files `admin.*` accordingly).

HINT: We are using Rails in version 7.1.2 in this example. You’ll need `node` and `yarn` installed for the whole JS ecosystem to work. 

Let’s start building:

```bash
rails new tailwind-bootstrap -j esbuild -c tailwind
```

The `-j` option tells Rails to install the `jsbundling-rails` gem as well. We defined `esbuild` as our JS bundler, but the other options such as bun, rollup.js etc. should work as well. Using `jsbundling-rails` also ensures that a `package.json` file ist created, `foreman` as a local process manager is installed and `yarn install` works. 

With the  `-c` option we define TailwindCSS as our CSS framwork. This will also install the necessary `cssbundling-rails` gem and install a working tailwind config named tailwind.config.js.

All those steps can also be done in an existing application. Just be sure to install the proper bundling gems and follow the steps along.

## Add the Bootstrap JS packages

Let’s also add the bootstrap related JS packages to the app. This is about the same that is done within the CSSbundling installer scripts.

```bash
yarn add sass bootstrap @popperjs/core
```

## Adjust the build scripts in package.json

We distinguish the build process for both Tailwind and Bootstrap here. Again, the build scripts are a direct copy of the installer script in the cssbundling-rails gem files. You can name the commands differently but be aware, that the cssbundling-rails gem expects a `build:css` command. It automatically attaches it to the `rake assets:precompile` task, so your deployments and your system tests should still work out of the box. Also specifically note the `load-path=node_modules` option for Bootstrap. This not only tells where to look for Bootstrap, but also allows to easily add additional packages with specific CSS bundled, like tagging packages, date pickers, etc.

```{
  ...
  "scripts": {
    "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=/assets",
    "build:css": "yarn build:tailwind && yarn build:bootstrap",
    "build:tailwind": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css --minify",
    "build:bootstrap": "sass ./app/assets/stylesheets/admin.scss ./app/assets/builds/admin.css --no-source-map --load-path=node_modules"
  },
  ...
}
```

## Adjust the Procfile.dev

The `cssbundling-rails` and `jsbundling-rails` gem install `foreman` as a process tool and a `Procfile.dev` file. In order to pick up both changes for tailwind and for bootstrap we need to adjust the processes with the build commands we just entered in the `package.json` file.

```bash
web: env RUBY_DEBUG_OPEN=true bin/rails server
js: yarn build --watch
tailwind: yarn build:tailwind --watch
bootstrap: yarn build:bootstrap --watch
```

## Add the Bootstrap CSS files

Since we already installed Tailwind CSS for our user facing part of the app while running the Rails generator, we can already proceed to Bootstrap for our admin part of the app. 

First we need to create the `admin.scss` file:

```bash
touch app/assets/stylesheets/admin.scss
```

Let’s load Bootstrap in this file:

```css
@import 'bootstrap/scss/bootstrap';
```

Let’s create the admin layout file as a initial copy of the application layout file:

```bash
cp app/views/layouts/application.html.erb app/views/layouts/admin.html.erb
```

Now replace the loading for the application styling file with the admin styling:

```diff
- <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
+ <%= stylesheet_link_tag "admin", "data-turbo-track": "reload" %>
```

## Add the Bootstrap JS files

To also take advantage of the Bootstrap JS functionality, we can basically do the same for the asset pipeline as we did for the CSS:

Let’s create an `admin.js` file:

```bash
touch app/javascript/admin.js
```

Place code to actually load the Bootstrap related JS, e.g.:

```javascript
// Entry point for the build script in your package.json
import '@hotwired/turbo-rails'
import * as bootstrap from 'bootstrap'

// Example for using a the bootstrap tooltip with turbo
document.addEventListener('turbo:load', () => {
  // tooltip component needs to be initialized
  const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
  tooltipTriggerList.map(function (tooltipTriggerEl) {
    return new bootstrap.Tooltip(tooltipTriggerEl)
  })
})
```

## Create controllers and views

We’ll create some quick controller and views to test everything out.

First add some dummy content for testing the Tailwind setup:

```bash
rails generate controller main index
```

Let’s add a test button styled with some Tailwind classes into `app/views/main/index.html.erb`:

```html
<button class="p-2 text-white bg-red-700 rounded bordered">I'm styled with Tailwind</button>
```

After that let’s repeat this for the admin setup with Bootstrap:

```bash
rails generate controller admin index
```

In the `app/views/admin/index.html.erb` file replace the generated content with:

```html
<button class="btn btn-primary">I'm styled with Bootstrap</button>
```


**Caution!** The AdminController autoloads the right layout because of our file naming naming. Adjust the layout call per controller if you have a different naming scheme.

## Test everything in the browser

Start your app processes with

```bash
bin/dev
```

and watch foreman informing you about the processes output. You should see the compilation step for Tailwind and Bootstrap.

Go to both `localhost:3000/main/index` and `localhost:3000/admin/index`. You should see Tailwind and Bootstrap working peacefully together! Their build output is dumped into `app/assts/builds/*` and  picked up by the standard Rails asset pipeline.

![Tailwind CSS and Bootstrap button in the same Rails app](https://github.com/dotruby/dotruby-content/assets/3856862/aa3947f6-71af-44f1-994e-55d5e8265fad)

## Cheers! 🎉

You're now running Tailwind CSS and Bootstrap side by side in your app. _Happy coding_!
