# Rails 7 Using React With ESBuild

> Set up a new Rails 7 project with ESBuild that has TypeScript support out-of-the-box.

- Canonical: https://dennisokeeffe.com/blog/2022-02-19-rails-7-using-react-with-esbuild
- Published: 2022-02-19
- Updated: 2022-02-19
- Tags: ruby, ruby-on-rails

This post will demonstrate how we can set up a Rails 7 project using [ESBuild](https://github.com/evanw/esbuild) to support our React + TypeScript applications.

Source code can be found [here](https://github.com/okeeffed/demo-rails-with-react-frontend)

## Prerequisites

1. Basic familiarity with setting up a [new Rails project](https://guides.rubyonrails.org/getting_started.html).

## Getting started

We will use Rails to initialize the project `demo-rails-with-react-frontend`:

```s
# Create a new rails project
$ rails new demo-rails-with-react-frontend -j esbuild
$ cd demo-rails-with-react-frontend

# Make some folders and files for our React application
$ mkdir app/javascript/components
$ touch app/javascript/components/application.tsx

# Add in our React dependencies
$ yarn add react react-dom

# Create a basic components controller
$ bin/rails g controller components index

# Start the server - we use `bin/dev` instead of `bin/rails s`
$ bin/dev
```

The above does the following:

1. Create a new Rails project in `demo-rails-with-react-frontend` with the `-j esbuild` flag to setup JavaScript with ESBuild.
2. Add in our React dependencies.
3. Create a basic components controller that we will set as our root route.
4. Start the server with `bin/dev`.

The `-j` flag for Rails helps us define which JavaScript setup we want. As denoted by the `bin/rails new --help` command:

```s
-j, [--javascript=JAVASCRIPT] # Choose JavaScript approach [options: importmap (default), webpack, esbuild, rollup]
```

We are overriding the default of `importmap` here.

At this stage, our project should be ready on `localhost:3000`, but there are a few other changes that we need to make first.

## Setting up our React Application

The first thing we want to do is setup our application to use React.

ESBuild will support TypeScript out of the box, so the first thing we want to do is update our file ``app/javascript/application.js` to `app/javascript/application.ts`.

> Note: given that `app/javascript/application.ts` is only for housing our imports, it will not be that necessary but we will do so anyway.

Inside of `app/javascript/application.ts`, update the file to the following:

```js
// Entry point for the build script in your package.json
import "@hotwired/turbo-rails";
import "./components/application";
```

We will leave the `@hotwired/turbo-rails` import as we found it, but then we will add a reference to `components/application` where our contrived React application code will go.

Finally, we want to update the code within `app/javascript/components/application.tsx` to the following:

```ts
import * as React from "react";
import * as ReactDOM from "react-dom";

interface AppProps {
  arg: string;
}

const App = ({ arg }: AppProps) => {
  return <div>{`Hello, ${arg}!`}</div>;
};

document.addEventListener("DOMContentLoaded", () => {
  const rootEl = document.getElementById("root");
  ReactDOM.render(<App arg="Rails 7 with ESBuild" />, rootEl);
});
```

The above code simply defines a React component that will be rendered to the DOM and has a TypeScript interface to prove TypeScript syntax is valid and working.

While the code is contrived (and not necessarily well organized with the whole `components/application.tsx` convention), it is a good example of how we can use ESBuild to support TypeScript and how we can set up our React component.

The last things that we need to do is update our view to provide the root `div` element with ID `root` and to update our `routes.rb` file to set our `components#index` method as our default.

## Updating our view and routes

During our `rails g controller components index` code that we ran at the beginning, we also generated the view `app/views/components/index.html.erb`.

Within that file, we need to add our div for our React app to hook into. Update the code in that file to the following:

```html
<h1>Components#index</h1>
<div id="root"></div>
```

Finally, within `config/routes.rb`, update the file to set components as the index default:

```rb
Rails.application.routes.draw do
  root 'components#index'
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Defines the root path route ("/")
  # root "articles#index"
end
```

Finally, we can head to `localhost:3000` and see our React application.

![React app](https://cdn.dennisokeeffe.com/assets/2022-02-19-rails-7-using-react-with-esbuild/1-react-application.webp)

## Summary

Today's post demonstrated how we can set up a Rails 7 project using ESBuild to support our React + TypeScript applications.

Rails 7 comes with a few neat options for how we can set up our project, and ESBuild is one of those options that comes out-of-the-box.

## Resources and further reading

- [Rails getting started](https://guides.rubyonrails.org/getting_started.html)
- [ESBuild](https://github.com/evanw/esbuild)
- [Source code](https://github.com/okeeffed/demo-rails-with-react-frontend)

_Photo credit: [`bencarless`](https://unsplash.com/@bencarless)_
