rails/rails
Initialization and railties
How a Rails application boots: the Railtie / Engine / Application hierarchy, the initializer DSL, and the boot phases.
The hierarchy
graph TD
Railtie["Rails::Railtie<br/>extension point"] --> Engine["Rails::Engine<br/>mountable mini-app"]
Engine --> Application["Rails::Application<br/>the user's app"]Rails::Railtie(railties/lib/rails/railtie.rb) is the smallest extension point. It can register initializers, generators, console hooks, runner hooks, and rake tasks. Every Rails framework defines one.Rails::Engine(railties/lib/rails/engine.rb) is a railtie that also has a directory layout (app/,config/,lib/), routes, migrations, and assets. Engines are mountable.Rails::Application(railties/lib/rails/application.rb) is an engine that's the root of the app. It owns the middleware stack, the route set, and the boot lifecycle. The user'sMyApp::Applicationinherits from it.
Where each component plugs in
Every framework defines a railtie (or engine):
| Component | File | Type |
|---|---|---|
| Active Support | activesupport/lib/active_support/railtie.rb |
Railtie |
| Active Model | activemodel/lib/active_model/railtie.rb |
Railtie |
| Active Record | activerecord/lib/active_record/railtie.rb |
Railtie |
| Action Controller | actionpack/lib/action_controller/railtie.rb |
Railtie |
| Action Dispatch | actionpack/lib/action_dispatch/railtie.rb |
Railtie |
| Action View | actionview/lib/action_view/railtie.rb |
Railtie |
| Action Mailer | actionmailer/lib/action_mailer/railtie.rb |
Railtie |
| Active Job | activejob/lib/active_job/railtie.rb |
Railtie |
| Action Cable | actioncable/lib/action_cable/engine.rb |
Engine |
| Action Mailbox | actionmailbox/lib/action_mailbox/engine.rb |
Engine |
| Action Text | actiontext/lib/action_text/engine.rb |
Engine |
| Active Storage | activestorage/lib/active_storage/engine.rb |
Engine |
| Test Unit | railties/lib/rails/test_unit/railtie.rb |
Railtie |
railties/lib/rails/all.rb requires all of them in dependency-aware order:
%w(
active_record/railtie
active_storage/engine
action_controller/railtie
action_view/railtie
action_mailer/railtie
active_job/railtie
action_cable/engine
action_mailbox/engine
action_text/engine
rails/test_unit/railtie
).each do |railtie|
begin
require railtie
rescue LoadError
end
endThe initializer DSL
Rails::Initializable (railties/lib/rails/initializable.rb) defines the initializer "name" macro:
class MyRailtie < Rails::Railtie
initializer "my_railtie.set_logger", before: :initialize_logger do |app|
app.config.logger ||= Logger.new(STDOUT)
end
endEach initializer declares a name and optional before: / after: ordering hints. Initializable::Collection performs a topological sort and runs them in dependency order.
Boot phases
The boot order is documented in the long comment at the top of railties/lib/rails/application.rb:
graph TD
A["1. require 'config/boot.rb'"] --> B[2. require railties + engines]
B --> C[3. Define Rails.application]
C --> D[4. before_configuration callbacks]
D --> E["5. Load config/environments/<env>.rb"]
E --> F[6. before_initialize callbacks]
F --> G[7. Run all railtie initializers]
G --> H[8. Run application initializers]
H --> I[9. Build middleware stack]
I --> J[10. to_prepare callbacks]
J --> K[11. before_eager_load + eager_load!]
K --> L[12. after_initialize callbacks]
L --> M[App ready]Bootstrap initializers
railties/lib/rails/application/bootstrap.rb declares the earliest initializers:
:load_environment_hook— invoke any pending environment-specific hooks.:load_active_support— require Active Support.:set_eager_load!— flipconfig.eager_loadbased on environment defaults.:initialize_logger— set upRails.logger.:initialize_cache— set upRails.cache.:initialize_dependency_mechanism/:bootstrap_hook— wire autoloading.
Application initializers
The user's config/initializers/*.rb files are run after the framework initializers. Each is wrapped in a Rails::Initializable::Initializer so they can reference Rails.application and Rails.configuration.
Finisher initializers
railties/lib/rails/application/finisher.rb declares the latest initializers:
:add_generator_templates:ensure_autoload_once_paths_as_subset:add_to_prepare_blocks— collectto_preparecallbacks into the executor.:build_middleware_stack— finalize the middleware ordering.:eager_load!— load every constant inconfig.eager_load_paths(production default).:finisher_hook
to_prepare
config.to_prepare { ... } registers a block that runs:
- Once during boot.
- Before every request in development (because the reloader re-runs
prepare).
This is the hook for "set up application-wide state that has to be reset on reload" — e.g., re-attaching observers to autoloaded classes.
Lazy load hooks
ActiveSupport.on_load(:active_record) do ... end registers a block that fires when (or after) ActiveRecord::Base is fully loaded. Implementation in activesupport/lib/active_support/lazy_load_hooks.rb. Used heavily for cross-framework integration without forcing eager require.
Standard hook names include :active_record, :active_record_fixtures, :action_controller, :action_view, :action_mailer, :active_job, :action_cable.
load_defaults
Rails::Application::Configuration#load_defaults(version) enables a curated set of recommended config for a given Rails version. The configuration source lives at the top of railties/lib/rails/application/configuration.rb. Each new defaults block adds:
- New default values for existing options.
- Flag-enabled features that flip on for the new version.
- Removals of options that are no longer used.
This is how Rails introduces breaking-by-default behavior without disrupting upgrades — apps that haven't bumped load_defaults keep the previous behavior.
Inspecting boot
In an app:
bin/rails initializers # The resolved initializer order
bin/rails middleware # The default middleware stack
bin/rails about # Versions, env, databaseImplementations:
railties/lib/rails/commands/initializers/initializers_command.rbrailties/lib/rails/commands/middleware/middleware_command.rbrailties/lib/rails/commands/about/about_command.rb
Engines
A Rails::Engine gets:
- A namespaced
app/,config/,lib/. - Its own routes, mounted under whatever path the host app chooses (
mount MyEngine::Engine => "/my"). - Its own migrations, copied via
bin/rails my_engine:install:migrations. - Its own assets and helpers.
Active Storage, Action Text, Action Mailbox, and Action Cable are all engines mounted into the host application.
Entry points for modification
- Adding an initializer to a framework: edit the framework's
railtie.rb(orengine.rb). - Reordering boot: add
before:/after:to an initializer declaration. - Adding a new lazy load hook: call
ActiveSupport.run_load_hooks(:my_hook, self)from the place where the class becomes "ready". - Adding a
load_defaultsblock: add awhen "8.3"case inapplication/configuration.rband document inguides/source/configuring.md.
Related pages
- packages/railties
- features/autoloading — Zeitwerk integration.
- reference/configuration — full
config.*reference.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.