rails/rails
Lore
A timeline of how the Rails codebase evolved. Dates come from git tags, commit timestamps, and changelogs. Where motivation isn't obvious from commits, language is hedged.
Eras
The Basecamp era (Nov 2004 – Aug 2008)
Rails was extracted from Basecamp by David Heinemeier Hansson. The first commit ("Initial") is dated 24 Nov 2004. The early code was a single tree containing what we'd now call Action Pack and Active Record; the monorepo split into the modern component layout came gradually.
Key events:
- Dec 2005 — Rails 1.0 released.
- Dec 2006 — Rails 1.2 introduces RESTful routing.
- Dec 2007 — Rails 2.0 (REST as the default, multi-database support).
- The community grew rapidly; many of the contributors who still rank in the top-20 commit list (Jeremy Kemper, José Valim, David Heinemeier Hansson) joined in this era.
The merger and the rewrite (Aug 2008 – Aug 2010)
Two big things happened:
- Dec 2008 — Rails merged with Merb. The Merb maintainers (José Valim, Yehuda Katz) joined the Rails core team, and Rails 3 absorbed Merb's modular architecture.
- Aug 2010 — Rails 3.0 released after a long beta. Action View was extracted from Action Pack, the router was rewritten on top of Journey (Aaron Patterson's tree-based engine), and the Railtie / Engine system became the canonical way to plug components together.
This era shaped the modular structure we have today: 12 components, Railtie as the extension point, bundler integration, and the Rails.application boot model.
The asset and async era (Aug 2010 – Aug 2016)
- Aug 2011 — Rails 3.1 introduces the Asset Pipeline (Sprockets), CoffeeScript and SCSS by default.
- Jan 2012 — Rails 3.2 ships query caches and faster routing.
- Jun 2013 — Rails 4.0 lands strong parameters, Turbolinks, and
Russian-dollview caching. - Apr 2014 — Rails 4.1 introduces secrets, mailer previews, and
enum. - Dec 2014 — Rails 4.2 ships Active Job and Adequate Record, GlobalID, and async mailers.
- Jun 2016 — Rails 5.0 brings Action Cable (WebSockets), API-only mode, and the
bin/railscommand unification.
The number of components grew steadily: Active Job (4.2), Action Cable (5.0).
The Webpacker and Active Storage era (Aug 2016 – Aug 2020)
- Apr 2017 — Rails 5.1 adds Active Record encrypted attributes (early form), Webpacker, system tests via Capybara/Selenium, and
form_with. - Apr 2018 — Rails 5.2 introduces Active Storage, encrypted credentials, content security policy DSL, and Bootsnap on by default.
- Aug 2019 — Rails 6.0 ships parallel testing, Action Mailbox, Action Text, multiple databases, and Zeitwerk autoloading.
- Dec 2020 — Rails 6.1 brings horizontal sharding, async queries, strict loading associations, and
where.missing.
The Hotwire era (Aug 2020 – present)
- Dec 2021 — Rails 7.0 makes Importmap and Hotwire (Turbo + Stimulus) the new default, ships Active Record encryption (proper, public API), zeitwerk-only autoloading, and async queries by default.
- Aug 2023 — Rails 7.1 introduces native composite primary keys, common-table expressions, the new
bin/devscript, andDockerfile+ Kamal integration. - Aug 2024 — Rails 7.2 ships dev containers, default browsers, and Action Cable + Active Storage simplifications.
- Sep 2024 — Rails 8.0 makes SQLite production-ready (WAL mode, queue, cache, cable), introduces Solid Queue, Solid Cache, Solid Cable as defaults, ships Kamal 2 and Thruster, removes Node from the default stack.
- 2025–2026 — Rails 8.1 and 8.2 (this snapshot) are landing PostgreSQL minimum bumps, deprecation of legacy connection options, frozen-string-literals by default in new apps, the
bin/rails queryread-only console, an offline PWA fallback, and continued cleanup of long-deprecated APIs.
Longest-standing features
These corners of the codebase have survived essentially every era:
ActiveSupport::Inflector— first introduced in 2004, still doing the same job (pluralize, singularize, camelize, classify). The implementation inactivesupport/lib/active_support/inflector/has been refactored but not replaced.Object#try— has been in Active Support since the late 2000s and has resisted multiple proposals to remove it in favor of&..Hash#with_indifferent_access— predates Ruby's modern hash literals and is still ubiquitous.- The
acts_as_list-style migration DSL (create_table do |t|) — survives unchanged from 2005. render :partial— still does what it did in Rails 1.0; the implementation has been rewritten several times for performance.
Major rewrites
- Routing → Journey (2010) — the regex-based router was replaced by a tree-based one in Rails 3. Lives at
actionpack/lib/action_dispatch/journey/. - Active Record query → Adequate Record (2014) — Rails 4.2 added a fast-path query cache that bypassed full Arel compilation for repeated queries.
activerecord/lib/active_record/relation.rband friends still bear its DNA. - Autoloading → Zeitwerk (2019) — Rails 6 introduced the Zeitwerk loader and made it the only option in 7. The shim layer in
activesupport/lib/active_support/dependencies/is much smaller than before. - Sprockets → Importmap / Propshaft (2021) — Rails 7 stopped requiring Sprockets. New apps default to Importmap; Propshaft is a leaner asset server. Integration code lives in
railties/lib/rails/generators/. - Action Cable wire format (2024) — the JS client was rewritten and the wire format simplified for Rails 8.
Deprecated features
A non-exhaustive sample of features that lived in the codebase and have been (or are being) removed:
Object#with_optionschained eagerly — softened in modern releases.mass_assignment_security/attr_accessible— removed in Rails 4 in favor of strong parameters.acts_asplugins — were replaced by composition (include).session_store: :cookiewith marshalled values — replaced with JSON to avoid object-injection attacks.config.action_view.raise_on_missing_translations— toggled on by default in 6.1 and now read at the application level.schema_orderandstrictPostgreSQL/MySQL options — currently being deprecated in 8.2 (seeactiverecord/CHANGELOG.md).- Sprockets integration — still present but no longer the default.
- Webpacker — extracted to a separate (now archived) repository.
- Node-based JS bundling in defaults — replaced by Importmap in 7.0 and removed from defaults entirely in 8.0.
Growth trajectory
- 2004–2007 — small core team, fast feature velocity.
- 2008–2014 — Merb merger, modular rewrite, contributor base widens to dozens of regular committers.
- 2015–2019 — corporate adoption broadens; companies like GitHub, Shopify, Basecamp, and Heroku land major changes (multi-DB, parallel tests, Zeitwerk).
- 2020–2024 — focus shifts to "no-build" frontend (Hotwire, Importmap), simpler deploys (Kamal), and SQLite-as-production. Active Record gets continual performance attention from Shopify (notably Jean Boussier's contributions).
- 2025–2026 — Rails 8 emphasizes "the One Person Framework": fewer external dependencies, Solid* adapters, and a leaner default stack.
The all-time top contributors (by commit count) include Rafael Mendonça França, Aaron Patterson, David Heinemeier Hansson, Ryuta Kamizono, Jeremy Kemper, Xavier Noria, Jean Boussier, José Valim, Carlos Antonio da Silva, and Eileen M. Uchitelle. See maintainers for component-by-component ownership.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.