How to Add Live Reload to Your Rails Application
Tags: rails, ruby, tutorial
Published: 2024-03-05 19:31:23

---
title: How to Add Live Reload to Your Rails Application
published: true
date: 2024-01-28 17:09:29 UTC
tags: rails, ruby, tutorial
canonical_url: https://webcrunch.com/posts/live-reload-rails
---

{% youtube Pf3Kpbb4ZHg %}


Live reload is an incredible tool for developers looking to boost their productivity. In this tutorial, I will walk you through implementing live reload in your Ruby on Rails application using esbuild.

Implementing live reload can significantly streamline your development workflow, saving you valuable time and effort. You can instantly see the results by automatically refreshing your app whenever you make changes without manually reloading the page.

To achieve this, we will leverage the power of esbuild, a cutting-edge technology for fast and efficient JavaScript bundling. By combining esbuild with Ruby on Rails, we can create a seamless live reload experience that will streamline your development process.

* * *

### Table of Contents

1. [Introduction](#introduction)
2. [Setting Up Your Rails Project](#setting-up-your-rails-project)
3. [Installing Necessary Gems and Dependencies](#installing-necessary-gems-and-dependencies)
4. [Configuring Esbuild](#configuring-esbuild)
5. [Creating the Live Reload Script](#creating-the-live-reload-script)
6. [Putting It All Together](#putting-it-all-together)
7. [Live reload alternatives for Ruby on Rails](#live-reload-alternatives)
8. [Conclusion](#conclusion)
9. [Continue learning](#continue-learning)

* * *

### Introduction

Live Reload automates the refresh process of your web page whenever you make changes to your code. This feature not only saves time but also enhances your overall development experience.

### Setting Up Your Rails Project

Start by creating a new Rails project with Tailwind CSS and esbuild:

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

### Installing Necessary Gems and Dependencies

First, ensure you have the `jsbundling-rails` gem installed. If not, add it to your Gemfile and run `bundle install`.

Next, set up esbuild with Rails:

```bash
./bin/bundle exec rails javascript:install:esbuild
```

Add the `chokidar` package for file watching:

```bash
yarn add chokidar -D
```

### Configuring esbuild

Create and customize an `esbuild.config.js` file in your project:

```javascript
# esbuild.config.js
const esbuild = require("esbuild")
const chokidar = require("chokidar")
const http = require("http")
const path = require("path")

const isProduction = process.env.RAILS_ENV === "production"
const watchMode =
  process.argv.includes("--watch") || process.argv.includes("--reload")
const reloadMode = process.argv.includes("--reload")
const port = 5678

// Esbuild configuration
const esbuildConfig = {
  entryPoints: [path.join("app/javascript", "application.js")],
  bundle: true,
  minify: isProduction,
  sourcemap: !isProduction,
  outdir: path.join("app/assets/builds"),
}

// Start the esbuild build process
esbuild.build(esbuildConfig).catch(() => process.exit(1))

// Set up a simple HTTP server for live reload with CORS headers
const clients = []
const server = http.createServer((req, res) => {
  // Set CORS headers
  res.setHeader("Access-Control-Allow-Origin", "*")
  res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS")
  res.setHeader("Access-Control-Allow-Headers", "Content-Type")

  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    Connection: "keep-alive",
  })

  clients.push(res)

  req.on("close", () => {
    clients.splice(clients.indexOf(res), 1)
  })
})

server.listen(5678)

// Watch for file changes 
chokidar
  .watch([
    "app/javascript/**/*",
    "app/views/**/*",
    "app/assets/stylesheets/**/*",
  ])
  .on("all", () => {
    esbuild.build(esbuildConfig)
    clients.forEach((client) => client.write("data: reload\n\n"))
  })

console.log("Live reload server running on http://localhost:5678")
```

This configuration sets up `esbuild` and a simple HTTP server for the live reload functionality.

Here's a simplified explanation of what the code in `esbuild.config.js` is doing, hopefully, broken down into more straightforward terms:

1. **Setting Up Tools and Checking the Environment** :
  - The code starts by loading some necessary tools: `esbuild`, `chokidar`, and `http`. `esbuild` helps in bundling and optimizing JavaScript files, `chokidar` watches for file changes, and `http` is used to create a server.
  - It checks if the Rails app is in production mode. This helps the code decide whether to optimize files for faster performance or not.
2. **Configuring Esbuild** :
  - A configuration is set for `esbuild`. This includes where to find the JavaScript files, whether to bundle them together and where to save them. It's like giving `esbuild` a map and a to-do list.
3. **Starting the Build Process** :
  - `esbuild` starts its job using the configuration provided. If something goes wrong, it stops the process to avoid more issues.
4. **Creating a Mini Server for Live Reload** :
  - The code sets up a small server. This server's job is to send messages to the web browser to refresh the page whenever there are changes.
  - It makes sure that any browser is allowed to connect to this server (that's what CORS headers do).
5. **Listening for Changes** :
  - `chokidar` starts watching files in your JavaScript, views, and stylesheets directories. Whenever there's a change in these files, it tells `esbuild` to rebuild them.
  - After rebuilding, it notifies all connected browsers to refresh the page. This means you see the changes in your web app immediately ✨.
6. **Running the Server** :
  - Finally, the server starts, and the code tells you that it's running and ready to reload your pages automatically on `http://localhost:5678`.

### Creating the Live Reload Script

Now, add a `live_reload.js` file to `app/javascript` and import it in `application.js`:

```javascript
// app/javascript/live_reload.js

if (process.env.NODE_ENV === "development") {
  const source = new EventSource("http://localhost:5678")
  source.onmessage = (event) => {
    if (event.data === "reload") {
      window.location.reload()
    }
  }
}
```

This script listens for the "reload" event cast from our esbuild configuration and refreshes the page. We created a new [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) for the server created by the `build` configuration.

### Putting It All Together

With these configurations, your Rails app is now set up for live reloading. You can start your Rails server and begin coding. The browser automatically reloads whenever you change your JavaScript, stylesheets, or views. This ultimately saves you time and sanity during development.

### Live reload Alternatives for Ruby on Rails

If you’re looking for alternatives to the esbuild-driven method I introduced in this tutorial, there are plenty of other options with Rails. Some options depend on specific technologies or front-end frameworks but accomplish similar goals.

1. **Guard LiveReload**
  - Description: Guard LiveReload automatically refreshes your browser when 'view' files are modified.
  - Link: [Guard LiveReload on GitHub](https://github.com/guard/guard-livereload)
2. **Rack::LiveReload**
  - Description: A Rack middleware that inserts the LiveReload script into your app's responses. Works well with apps not using Webpacker.
  - Link: [Rack::LiveReload on GitHub](https://github.com/jaredmdobson/rack-livereload)
3. **Webpacker**
  - Description: Though primarily for managing JavaScript, Webpacker can be configured for hot module replacement, similar to live reloading.
  - Link: [Webpacker on GitHub](https://github.com/rails/webpacker)
4. **BrowserSync**
  - Description: Not specific to Rails, BrowserSync can synchronize file changes and interactions across multiple devices, ideal for responsive testing.
  - Link: [BrowserSync](https://browsersync.io/)
5. **React Hot Loader**
  - Description: React Hot Loader enables hot module replacement for a smoother development experience if you use React with Rails.
  - Link: [React Hot Loader on GitHub](https://github.com/gaearon/react-hot-loader)
6. **Vite Ruby**
  - Description: Vite Ruby integrates Vite.js with Ruby on Rails, offering a fast front-end build tool with features like hot module replacement.
  - Link: [Vite Ruby on GitHub](https://github.com/ElMassimo/vite_ruby)

### Conclusion

Live Reload is an awesome tool for enhancing your Rails development workflow. It reduces the time spent on manual refreshes, allowing you to focus more on development. The result is more efficient coding and better development of apps.

### Continue learning

- [How to use bun with Ruby on Rails](https://%5Bhttps://webcrunch.com/posts/bun-with-ruby-on-rails%5D(https://webcrunch.com/posts/bun-with-ruby-on-rails))
- [Digging into Turbo 8's Morphing Feature in Ruby on Rails](https://webcrunch.com/posts/turbo-morphing-ruby-on-rails)
- [Digging into Turbo with Ruby on Rails 7](https://webcrunch.com/posts/digging-into-turbo-with-ruby-on-rails-7)