Ruby on Rails and ReactJS are two distinct frameworks in software development. RoR is primarily used for the backend, while React is a popular choice for the frontend of interactive web applications. When you use Ruby on Rails with React together, they complement each other, leveraging the strengths of each. This article focuses on the strengths of both frameworks and provides insights into how Ruby on Rails can be used with React, along with their advantages.
At Rubyroid Labs, we have a continuously growing portfolio of projects built on Ruby on Rails and ReactJS. With a presence in the IT development market since 2013, we combine expertise with solid experience to bring your next project to life. Let’s start discussing it now — just fill in this short form and we’ll get back to you within 24 business hours.
Why You Should Choose Ruby on Rails for the Backend
It accelerates software development. Ruby on Rails is built on two principles — Conventions over Configurations and Don’t Repeat Yourself (DRY) — which greatly accelerate web development.
According to the CoC principle, when you follow the established conventions, you develop apps in less time and with fewer lines compared to using languages like Java or Node. The DRY principle encourages developers to create concise and reusable code to avoid duplication.
When applied, these two principles reduce the number of decisions developers need to make in order to build applications, as well as improve code quality. The statistics speak for themselves: developers using Ruby on Rails accelerate software development by 30-40% compared to other programming languages.
It has an extensive library of gems. Ruby on Rails has more than 160 000+ free libraries, released as gems, with over 149+ billion downloads. These gems expand the core functionality of web applications; so if you need to add additional features, you’re likely to find them in one of these libraries. Here are the top three gems:
- Devise — a gem for user authentication and authorization, offering features like password encryption, email confirmation, and recovery;
- CarrierWave — a gem that simplifies file uploads and management, including image resizing, file validation, and storage;
- ActiveAdmin — a gem used to create customized admin dashboards, pages, and reports tailored to the specific needs of administrators.
It is a highly secure framework. RoR provides protection against cross-site scripting, request forgery, SQL injection, and security against web-based attacks and phishing. It also employs REST API, encouraging developers to adhere to standard protocols for their web applications. These attributes make companies like Shopify, Zendesk, and Airbnb choose Ruby on Rails for their server-side development.
It is a cost-effective solution. Ruby on Rails is an open-source framework that is completely free with no licensing fees attached. Since the frameworks already include pre-built components and gems, which developers can download from GitHub, it reduces potential development costs.
Why You Should Use React for The Frontend
React is flexible. Because React supports a modular structure through its component-based architecture, developers can build user interfaces by breaking them down into smaller components. Each component focuses on separate pieces of functionality and can be reused in other parts of an app or project. This modularity provides the freedom to create more complex interfaces, organize dependencies, and maintain apps. At Rubyroid Labs, we rely on this flexibility offered by a framework when building ReactJS mobile and web applications.
React supports fast rendering. Virtual Document Object Model, also known as Virtual DOM, is a major reason for the fast rendering of apps built with React. It serves as a lightweight representation of the actual DOM, mirroring the structure and content of web pages. When the changes are made, they are first applied to the Virtual DOM, reducing the amount of interactions with the actual DOM, which can be slow and resource-intensive. After that, a diffing algorithm determines a small set of changes that should be applied to the actual DOM, resulting in an overall fast rendering of apps.
React has a declarative syntax. With React’s declarative syntax, developers can describe how the UI state should look like, instead of providing exact steps to achieve it, which then is used to update the DOM. This approach leads to easier-to-understand code, which also results in the ease of identifying and troubleshooting issues.
At Rubyroid Labs, our approach is to provide our clients with frontend choices that benefit their product potential. This is how we ended up using ReactJS on the frontend for one of our clients, NNOXX. We developed a platform that tracks data from a wearable device measuring nitric oxide levels in the blood. The platform offers various levels of analytics that customers can view through a mobile app or a web interface.
How to use React and Ruby on Rails in 2024
While ReactJS and Ruby on Rails are two separate frameworks, they can work in tandem to help developers create more complex applications. There are two common ways to use Ruby on Rails with ReactJS:
Two separate applications with API communication. In this approach, you build two standalone apps: one for the frontend built with React, and another for the backend built with Ruby on Rails. These two apps communicate via API requests. This approach allows you to decouple the frontend and backend, enabling them to operate independently.
Ruby on Rails app with React library. In this approach, you build a Ruby on Rails application and connect the React library to the frontend. Developers working on the client side will use JS libraries without modifying the code as per the Rails framework standards. This approach is especially useful for smaller applications and situations where you want a more integrated development approach. Additionally, this approach eliminates the need to develop an API, resulting in faster development.
While the choice of an approach depends on your architectural preferences, you can rely on the expertise of Rubyroid Labs to execute the development from start to finish.
Why use ReactJS with Ruby on Rails?
It leads to a faster time-to-market. Ruby on Rails has developer-friendly features, plugins, and coding libraries compatible with React app components. When ReactJS and Ruby are used together, they reduce development time and accelerate the app’s launch to the market.
It helps you create more complex apps. Ruby on Rails is a mature framework for building the back-end part of an application, offering a wide range of features for managing databases, handling authentication, and dealing with routing. React is used to build user interfaces, featuring a component-based architecture and a virtual DOM to create dynamic and responsive front-end experiences. This combination of distinct frameworks makes it a powerful stack for building web apps.
It is a reliable and stable combination for web development. Both frameworks have active communities, receive regular updates, and offer advanced features, boosting web development practice. This combination of frameworks is used by such giants as X (Twitter), Crunchbase, Airbnb, and GitHub, adding a piece of reliability for building web applications using React with Ruby on Rails.
To see how these frameworks work paired together, consider our own project: we built a corporate website using RoR on the backend and the Gatsby.js framework on the frontend. This pairing resulted in a significant increase in page speed to 94/100 and enabled us to create an interactive website filled with animated blocks.
How to integrate Ruby on Rails and React: Tutorial
To show you the practical integration of Ruby on Rails with the React library, we’re going to create an application with sports exercises. This Ruby and React tutorial consists of 7 steps, each with code implementations, so you can copy code lines and implement them in your project.
Step 1. Create a Rails application
In Ruby on Rails, the process of creating a new application starts with the new command in your terminal:
$ rails new rails_react_exercise -d postgresql -j esbuild -c bootstrap -T
There are two actions this command performs. First, it places your application in the rails_react_exercise root directory where you can find all files associated with your project. Second, it allows to automatically create Ruby and JavaScript dependencies needed for accelerated website development; and it configures Webpack, the JavaScript bundler.
There are four flags that come with the new command: the -d, -j, -c, and -t. They help to customize the set of the initialization process. For example, the -d flag points out the preferred database engine, while the -j flag specifies esbuild as the preferred bundler.
In the root directory, open its contents with the following command:
$ cd rails_react_exercise
$ ls
You will get a preview of files and folders that are the structure of your Rails application.
Step 2. Connect your application to a database
After you create a Rails project, it needs to be connected to a database. This Ruby on Rails React tutorial focuses on the PostgreSQL database where you store the user intent data.
The good thing about Rails is that it provides commands to accelerate the web development process and manage the database schema with the create, drop, and reset commands.
The process of creating a database is straightforward. Run the rails db:create command to create a development and test database.
Start your application with the bin/dev command; you should have the following output on your screen:
started with pid 70099 started with pid 70100 started with pid 70101 yarn run v1.22.10 yarn run v1.22.10 $ esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets --watch $ sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules --watch => Booting Puma => Rails 7.0.4 application starting in development => Run `bin/rails server --help` for more startup options [watch] build finished, watching for changes... Puma starting in single mode... * Puma version: 5.6.5 (ruby 3.1.2-p20) ("Birdie's Version") * Min threads: 5 * Max threads: 5 * Environment: development * PID: 70099 * Listening on http://127.0.0.1:3000 * Listening on http://[::1]:3000 Use Ctrl-C to stop Sass is watching for changes. Press Ctrl-C to stop
Go to http://localhost:3000 in order to see your application. You should have the default welcome page, which means that you set up your app correctly.
Step 3. Install React Frontend dependencies
The next step involves installing React js dependencies:
- React, which is the core library useful for interfaces;
- React DOM, which renders React elements into the DOM;
- React Router, responsible for handling navigation in your app;
To set them up, use the $ yarn add react react-dom react-router-dom command with the Yarn package manager. You can find installed dependencies in the package.json file.
In order to see the list of installed packages, check them under the dependencies:
{ "name": "app", "private": "true", "dependencies": { "@hotwired/stimulus": "^3.1.0", "@hotwired/turbo-rails": "^7.1.3", "@popperjs/core": "^2.11.6", "bootstrap": "^5.2.1", "bootstrap-icons": "^1.9.1", "esbuild": "^0.15.7", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.3.0", "sass": "^1.54.9" }, "scripts": { "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets", "build:css": "sass ./app/assets/stylesheets/application.bootstrap.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules" } }
Step 4. Create the Homepage
The next step is to create a homepage where users land when they open your application.
Rails follows the Model-View-Controller architecture pattern, which receives user input and passes the data to the appropriate model or view.
Rails also has a controller component generator to create controllers; those are responsible for handling and processing user inputs, and updating the model and view.
In this Ruby on rails and React tutorial, we’re going to create a basic component related to handling requests for a homepage. Let’s create a Homepage controller with an index action:
$ rails g controller Homepage index
This command has generated three new pages:
- A homepage_controller.rb file that receives requests related to a homepage;
- A homepage_helper.rb file that includes helper methods for a Homepage controller;
- An index.html.erb file that serves as a view page for rendering homepage-related actions;
Besides these new pages, Rails also updates your routes file at config/routes.rb by adding a get route for a homepage. To set it up, follow this command:
$ nano config/routes.rb
In this file you see, replace get ‘homepage/index’ with root ‘homepage#index’. You should get an output similar to the one below:
Rails.application.routes.draw do root 'homepage#index' # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
With this change, Rails sets the root URL to the index action of the Homepage Controller, making the homepage the default landing page for your app.
Run your application to ensure that it starts with the landing page.
Next, open the ~/rails_react_exercise/app/views/homepage/index.html.erb file. Remove the code and save the file as empty; it will ensure that the contents of index.html.erb render separately from your frontend part.
Step 5. Configure React as your Rails Frontend
With React being on the frontend part of your app, you can excel at creating a dynamic and interactive homepage.
While most of the settings for seamless work between React and Rails are in place, you need to configure the esbuild entry point for JavaScript files.
To do this, create a components directory in the app/javascript directory — it’s where components for the entire application will be housed, including the entry file. Run this command:
$mkdir ~/rails_react_exercise/app/javascript/components
Then, open the application.js file with the following command:
$nano ~/rails_react_exercise/app/javascript/application.js
Add import “./components” to the last row of your command preview.
With the directory imported into the entry point, now you can proceed to create a component for the homepage that will have content and a CTA button to view all exercises.
For that, create a Home.jsx file in the components directory to extend JavaScript code:
$nano ~/rails_react_exercise/app/javascript/components/Home.jsx
And add the following code to the file:
import React from "react"; import { Link } from "react-router-dom"; export default () => ( <div className="vw-100 vh-100 primary-color d-flex align-items-center justify-content-center"> <div className="jumbotron jumbotron-fluid bg-transparent"> <div className="container secondary-color"> <h1 className="display-4">Sport exercises</h1> <p className="lead"> A list of sport exercises to boost your workout. </p> <hr className="my-4" /> <Link to="/exercises" className="btn btn-lg custom-button" role="button" > View Exercises </Link> </div> </div> </div> );
As you can see from above, it has the Link component from React Router, which helps users to navigate from one page to another in your app.
Now it’s time to create the routes directory. It has corresponding components, which are rendered to a browser when a route is loaded. Run this command:
$mkdir ~/rails_react_exercise/app/javascript/routes
Then, create an index.jsx file:
$nano ~/rails_react_exercise/app/javascript/routes/index.jsx
Add the following code to it:
import React from "react"; import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import Home from "../components/Home"; export default ( <Router> <Routes> <Route path="/" element={<Home />} /> </Routes> </Router> );
In the code above, you’ve added the following modules:
- The React module, which is the core library that allows you to use React components;
- BrowserRouter, Routes, and Route modules that allow you to navigate between pages;
- The Home component, which renders a specific component when a request matches the root route.
Now that you have these modules, you can set up routing using React Router. For that, create an App.jsx file in the app/javascript/components directory:
$nano ~/rails_react_exercise/app/javascript/components/App.jsx
Add the code below to the file:
import React from "react"; import Routes from "../routes"; export default props => <>{Routes}</>;
Render your App.jsx file in the entry file by running the following code:
$nano ~/rails_react_exercise/app/javascript/components/index.jsx
Then, add the following lines to your command:
import React from "react"; import { createRoot } from "react-dom/client"; import App from "./App"; document.addEventListener("turbo:load", () => { const root = createRoot( document.body.appendChild(document.createElement("div")) ); root.render(<App />); });
When the routing is set up, you can add CSS styles to your homepage. For that, open the application.bootstrap.scss file in your ~/rails_react_exercise/app/assets/stylesheets/application.bootstrap.scss directory and replace data with the code below:
@import 'bootstrap/scss/bootstrap'; @import 'bootstrap-icons/font/bootstrap-icons'; .bg_primary-color { background-color: #FFFFFF; } .primary-color { background-color: #FFFFFF; } .bg_secondary-color { background-color: #293241; } .secondary-color { color: #293241; } .custom-button.btn { background-color: #293241; color: #FFF; border: none; } .hero { width: 100vw; height: 50vh; } .hero img { object-fit: cover; object-position: top; height: 100%; width: 100%; } .overlay { height: 100%; width: 100%; opacity: 0.4; }
By running this command, you just:
- Defined primary, secondary, and background colors;
- Defined the style of buttons on a page by running the custom-button.btn class;
- Added a hero image on the front page with a .hero section.
Step 6. Create the Exercise Model and Controller
The next step in the React Rails installation script is to create the exercise model and controller.
While the model contains information about the exercises, the controller handles users’ requests and interacts with the database in order to retrieve data and send it to the browser.
In order to create an Exercise model, run the following command:
$ rails generate model Exercise name:string trainings:text instruction:text image:string
This command generated two files: one is the exercise.rb file that holds the model-related logic, and another one is the 20221017220817_create_exercise.rb file, which contains instructions for a database table where the Exercise data is stored.
To ensure that your database contains only valid data, you need to add database validation. For that, open your exercise model located at app/models/exercise.rb and add these lines to the code:
validates :name, presence: true validates :trainings, presence: true validates :instruction, presence: true
These lines confirm that exercises are saved to your database. To ensure that the migration works with your database, let’s create the exercises table by running this command:
$ nano ~/rails_react_exercise/db/migrate/20221017220817_create_exercices.rb
Add the highlighted code to your terminal output:
class CreateExercises < ActiveRecord::Migration[5.2] def change create_table :exercises do |t| t.string :name, null: false t.text :trainings, null: false t.text :instruction, null: false t.string :image t.timestamps end end end
Now you need to create the exercises controller; for that, run the following command:
$ rails generate controller api/v1/Exercises index create show destroy --skip-template-engine --no-helper
After running this command, Rails will generate a ExercisesController file in the app/controllers/api/v1 directory with index, create, show, destroy actions.
To use these routes, you need to add highlighted lines to your code:
$ nano ~/rails_react_exercise/config/routes.rb
Rails.application.routes.draw do namespace :api do namespace :v1 do get 'exercises/index' post 'exercises/create' get '/show/:id', to: 'exercises#show' delete '/destroy/:id', to: 'exercises#destroy' end end root 'homepage#index' get '/*path' => 'homepage#index' # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Defines the root path route ("/") # root "articles#index" end
To check the available list of actions, run the $ rails routes command. To ensure they run correctly, you need to add the logic to get exercises at once — the ActiveRecord library will help with that. For that, open your exercises_controller.rb file and add highlighted rows:
class Api::V1::ExercisesController < ApplicationController def index exercise = Exercise.all.order(created_at: :desc) render json: exercise end def create end def show end def destroy end end
Next, you need to add the logic for creating new exercises; for that, update your controller with the following highlighted code:
class Api::V1::ExercisesController < ApplicationController def index exercise = Exercise.all.order(created_at: :desc) render json: exercise end def create exercise = Exercise.create!(exercise_params) if exercise render json: exercise else render json: exercise.errors end end def show end def destroy end private def exercise_params params.permit(:name, :image, :trainings, :instruction) end end
After all that has taken place, save changes and close the file.
Step 7. Create a component for creating exercises
In this step, we’re going to create an app component that allows users to create new exercises. When the component collects exercise details from a user, it then saves the data in the Exercise controller.
To start, let’s create a NewExercise.jsx file in the app/javascript/components directory:
$ nano app/javascript/components/NewExercise.jsx
Import the React, Link, useState, and useNavigate modules into the file:
import React, { useState } from "react"; import { Link, useNavigate } from "react-router-dom";
Run this command below to create and export a NewExercise component:
const NewExercise = () => { const navigate = useNavigate(); const [name, setName] = useState(""); const [trainings, setTrainings] = useState(""); const [instruction, setInstruction] = useState(""); }; ; export default NewExercise;
As you see, the code above has a name, trainings, and instructions states that your users would need to create a new exercise.
The next step would be to create a stripHtmlEntities function to represent characters with special meanings and not letting it store raw HTML in your database; for that, add the following lines to your running command:
const stripHtmlEntities = (str) => { return String(str) .replace(/\n/g, "<br> <br>") .replace(/</g, "<") .replace(/>/g, ">"); };
To add a function of editing and submitting a form with new exercises, add the onChange and onSubmit functions with the following lines of code:
const onChange = (event, setFunction) => { setFunction(event.target.value); }; const onSubmit = (event) => { event.preventDefault(); const url = "/api/v1/exercises/create"; if (name.length == 0 || trainings.length == 0 || instruction.length == 0) return; const body = { name, trainings, instruction: stripHtmlEntities(instruction), }; const token = document.querySelector('meta[name="csrf-token"]').content; fetch(url, { method: "POST", headers: { "X-CSRF-Token": token, "Content-Type": "application/json", }, body: JSON.stringify(body), }) .then((response) => { if (response.ok) { return response.json(); } throw new Error("Network response was not ok."); }) .then((response) => navigate(`/exercises/${response.id}`)) .catch((error) => console.log(error.message)); };
To protect an application from Cross-Site Request Forgery attacks, Rails includes a CSRF token to the HTML document. On the server side rendering part, Rails verifies the received CSRF token and the expected one. If the tokens match, the server processes the request; otherwise, it throws out an exception, indicating a potential CSRF attack.
As the last step of this Ruby on Rails with React tutorial, add the markup for a form where users can add details for their exercises:
return ( <div className="container mt-5"> <div className="row"> <div className="col-sm-12 col-lg-6 offset-lg-3"> <h1 className="font-weight-normal mb-5"> Add a new exercise to our exercise collection. </h1> <form onSubmit={onSubmit}> <div className="form-group"> <label htmlFor="exerciseName">Exercise name</label> <input type="text" name="name" id="exerciseName" className="form-control" required onChange={(event) => onChange(event, setName)} /> </div> <div className="form-group"> <label htmlFor="exercisetraining">Trainings</label> <input type="text" name="trainings" id="exerciseTrainings" className="form-control" required onChange={(event) => onChange(event, setTrainings)} /> <small id="trainingsHelp" className="form-text text-muted"> Separate each training with a comma. </small> </div> <label htmlFor="instruction">Preparation Instructions</label> <textarea className="form-control" id="instruction" name="instruction" rows="5" required onChange={(event) => onChange(event, setInstruction)} /> <button type="submit" className="btn custom-button mt-3"> Create Exercise </button> <Link to="/exercises" className="btn btn-link mt-3"> Back to exercises </Link> </form> </div> </div> </div> );
To access this component on your browser, update the route file with these two lines:
import NewExercise from "../components/NewExercise"; <Route path="/exercise" element={<NewExercise />} />
To check your new Rails and React application, go to the http://localhost:3000 site. There, you will find the Exercises page and a button to create new training. Click on it to access a form where you can add new exercises.
If you need help creating a web or mobile application built using the React and Rails approach, Rubyroid Labs developers are ready to assist you.
Final thoughts
Using React and Ruby on Rails together in 2024 is a way to create well-structured and maintainable applications. Both ReactJS and Ruby on Rails provide access to strong community support and excel in their respective roles for frontend and backend development. To make your final application shine, Rubyroid Labs is ready to assist you throughout the web and mobile app development, from ideation to market release.
Whether you want a single-page app or a complex and interactive user interface — we will leverage the full potential of React library and Ruby on Rails features to deliver a product that pleases your customers. Contact us to schedule a consultation.
FAQ
Is Ruby on Rails faster than Node.js?
Overall, Node.js offers high performance and speed, so you can expect a high level of real-time functionality. However, if you prioritize the productivity of developers, and leverage the ecosystem of libraries and tools offered by Ruby on Rails, you can excel in fast development cycles similar to development on Node.js.
Can I use React with Ruby on Rails as a combination?
Yes. You can choose one of two development approaches. The first one states that you need to build two standalone apps: one for the frontend built with React, and another for the backend built with Ruby on Rails. These apps will communicate via API requests. Another approach is to build a Ruby on Rails application and connect the React library to the frontend part of an app. You can find more information in our React Ruby on Rails tutorial.
Can I use Ruby on Rails for frontend?
Yes, you can use Ruby on Rails for the frontend, as Rails is a full-stack web application framework. This means that developers can leverage it to create both the Rails backend and frontend of an application. If you have a small and simple app, using Ruby on Rails on the frontend would streamline your development process more than using React.