Open-source project
rails/rails avatar
rails/rails

Rails is a dozen component directories, and only three of them build JavaScript

GitHub describes it as Ruby on Rails. The repository metadata lists Ruby as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

58,785 stars23,998 forksRubyMIT

At a glance

What is it?
Rails is a Ruby web application framework organized around Model, View, and Controller layers, with eleven named frameworks and libraries bundled alongside them. Two of its conventions surprise newcomers: a model does not have to be database-backed, and declaring a background job does not run one.
Who is it for?
Rails fits a team that wants a database-backed application with routing, ORM, mail, background jobs, file attachments, and WebSockets already wired to one convention, and that is willing to learn where those conventions live. It is a poor fit if you want a small library, or if your domain is not rows in a table and you would rather not carry an ORM.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The model layer does not have to be a database

Rails describes itself as a framework for database-backed web applications, and the Model layer is where that shows. Model classes are derived from ActiveRecord::Base, and Active Record is what lets you present the data from database rows as objects and embellish those objects with business logic methods. But the same paragraph draws a boundary. Although most Rails models are backed by a database, models can also be ordinary Ruby classes, or Ruby classes that implement a set of interfaces as provided by the Active Model module. What that means in practice is that the database coupling is a convention you can decline. If your domain is not rows in a table you can model it in plain Ruby and satisfy the interfaces Rails expects, and nothing forces a table behind every object. The cost of that freedom is that you give up Active Record's persistence and query behavior for those objects, and you own whatever replaces it.

A controller is not just an HTML generator

Returning HTML is the usual case for a Rails controller, but the framework is explicit that controllers can also generate XML, JSON, PDFs, mobile-specific views, and more. The request path is worth naming because it explains where that decision happens. Incoming requests are routed by Action Dispatch to an appropriate controller, and controller classes are derived from ActionController::Base, with Action Dispatch and Action Controller bundled together in Action Pack. What this cannot do is choose the format on your behalf, and that is the point worth holding onto. A controller answering JSON and a controller answering HTML are the same class with a different response decision, so a reader who assumes every Rails endpoint returns a rendered page will mispredict how errors, redirects, and content negotiation behave. Nothing in the routing step knows what you meant to return.

Views render email bodies as well as web responses

The View layer is composed of templates that provide appropriate representations of your application's resources, and most of them are HTML with embedded Ruby code, in ERB files. The part that catches people out is where those templates get used. Views are typically rendered to generate a controller response or to generate the body of an email, and view generation is handled by Action View. What this cannot do is keep those two contexts apart for you. A mailer view and a page view are both templates passing through the same layer, so a change to a shared partial reaches an email body as readily as a web page, and a template that assumes a request object can break a mail that renders the same partial. Templates can also come in formats other than HTML, which widens the surface rather than narrowing it.

Action Job declares the work but does not run it

Action Job is described as a framework for declaring jobs and making them run on a variety of queuing backends, and that phrasing is carrying real weight. Declaring a job is what the framework hands you. Execution belongs to a backend. The README does not name a default backend or enumerate the adapters, so the question of what actually runs your background work is one you answer from other documentation rather than from this page. The same pattern shows up in the neighboring components: Action Storage attaches cloud and local files, Action Cable integrates WebSockets, Action Mailbox receives email inside the application, and Action Text handles rich text content. Each is a capability, and each still has infrastructure behind it that the framework describes the interface to without shipping for you.

Only three of the components carry a JavaScript build

The repository root holds a package.json, and it is small. It is marked private and declares workspaces for exactly three directories: actioncable, actiontext, and activestorage. There is a yarn.lock and a .yarnrc alongside it, plus an eslint config for the JavaScript side. Every other component directory, from activerecord and activesupport through to railties, has no entry in that workspace list. What that split means is that the JavaScript toolchain is a fact about three components and not a fact about Rails. If you are contributing to Action Pack or Active Job you never enter the yarn build, and if you are contributing to Action Cable or Action Text you do. A reader who assumes a JavaScript toolchain spans the repository will lose time looking for a workspace that does not exist.

Two release lines received patches on the same day

The release history shows two supported lines moving together. Version 8.1.4 and version 7.2.4 were both published on 2026-09-24, and a patch on the 8.1.3 line, version 8.1.3.1, went out on 2026-07-29. The repository was last pushed to on 2026-09-29. What this means for an adopter is that Rails is versioned as lines you stay on rather than a single moving target, so installing the gem without a constraint puts you on the newest line while an application that pinned 7.2 is still collecting fixes. The practical consequence is that installing the gem straight is the wrong tool for reproducing a build, and the files that pin a real one live in the repository, among them Gemfile.lock, rails.gemspec, and the RAILS_VERSION file, with the procedure written down in RELEASING_RAILS.md.

gem install rails and bin/rails are two different commands

Getting started takes three commands, and the third one is not the first one repeated. You install the framework as a gem:

bash
$ gem install rails

then generate an application:

bash
$ rails new myapp

and start it from inside the generated directory using the application's own binary:

bash
$ cd myapp
$ bin/rails server

Run it with --help or -h for options. The application is then at http://localhost:3000, where the bootscreen shows your Rails and Ruby versions. What this cannot do is reconcile those two versions for you. The global gem that generated the application and the version recorded in the application's lockfile are separate, so a machine carrying a newer gem than the project expects can generate an app, or run a task, against a different Rails than the one you deploy. Read the version off the bootscreen before trusting the environment.

Style rules are enforced separately for Ruby, Markdown, and JavaScript

Contributing to Rails means satisfying several unrelated linters rather than one. The root carries a .rubocop.yml for Ruby, a .mdlrc with a companion .mdlrc.rb for Markdown, an eslint.config.mjs for JavaScript, and a .yardopts for the generated API documentation, alongside a code of conduct and a separate security policy for reporting a possible vulnerability. There is also a .git-blame-ignore-revs file, which is how the project keeps mass reformatting commits out of blame history, plus a Brewfile and a devcontainer definition for local setup. What this cannot do is collapse into a single command you can reason about. The cost lands on the contributor rather than the user, and it means a change that is functionally correct can still be turned away on formatting, with the relevant config sitting in a different file for each language the change touches.

Editorial conclusion

Rails fits a team that wants a database-backed application with routing, ORM, mail, background jobs, file attachments, and WebSockets already wired to one convention, and that is willing to learn where those conventions live. It is a poor fit if you want a small library, or if your domain is not rows in a table and you would rather not carry an ORM. Before you commit, confirm you can pin a release line rather than tracking the newest gem, read the version off the bootscreen against your lockfile, and remember that declaring a job does not mean something is running it.

Frequently asked questions

What are Rails?

Rails is a web application framework that includes everything needed to create database-backed web applications according to the Model-View-Controller pattern, which divides an application into Model, View, and Controller layers, each with a specific responsibility.

What does Ruby on Rails include out of the box?

Beyond the Model, View, and Controller layers, Rails ships Action Mailer for generating and sending email, Action Mailbox for receiving it inside the application, Action Job for declaring jobs, Action Cable for WebSockets, Action Storage for attaching cloud and local files, Action Text for rich text, and Action Support for utility classes and standard library extensions.

How do I start a new Ruby on Rails application?

Install the gem with gem install rails, generate an application with rails new myapp, then change into that directory and run bin/rails server, using --help or -h for options. The app is then reachable at http://localhost:3000, where the bootscreen shows your Rails and Ruby versions.

Can I use parts of Ruby on Rails outside Rails?

Yes. Active Record, Active Model, Action Pack, and Action View can each be used independently outside Rails, and Action Support may also be used independently. Action Pack bundles Action Dispatch and Action Controller together, while the Model layer can be plain Ruby classes satisfying the Active Model interfaces instead of database-backed records.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rails-rails.svg)](https://hysenlabs.com/projects/rails-rails)