Rails 6 → Rails 7
This guide covers upgrading from Rails 6 to Rails 7. The defining change is that Zeitwerk becomes the only autoloader, so the app may fail to boot until file and constant names line up. The asset story also shifts from Webpacker to import maps / jsbundling / cssbundling.
Last verified · Updated May 22, 2026
Migrating from Rails 6 to Rails 7. The defining change is that Zeitwerk is now the only autoloader — the classic autoloader is gone — so the app may not boot until file names match constant names. Webpacker is also replaced by import maps / jsbundling / cssbundling. Treat this as high-risk because it touches autoloading, assets, and likely the database.
Should you upgrade directly?
Yes, this is a single supported major step — but do not skip it on the way to Rails 8. Get the app booting under Zeitwerk and the suite green on Rails 7 first, then advance config.load_defaults to 7.0 and tackle the asset-pipeline move before considering Rails 8.
Key differences
- Zeitwerk is the only autoloader — file/constant naming must be exact or boot fails.
- Webpacker is replaced by import maps (default), jsbundling, and cssbundling.
- Active Record encrypted attributes (encrypts) ship in the framework.
- Asynchronous queries via load_async for parallelizing slow reads.
- config.load_defaults 7.0 flips a batch of new framework defaults.
Files and patterns to inspect
- lib/ and app/ files with non-conventional names that Zeitwerk will reject.
- require_dependency calls and manual eager_load_paths tweaks.
- config/webpacker.yml and any Webpacker packs to migrate to importmaps/jsbundling.
- config/application.rb — the current config.load_defaults value.
- Pending and irreversible database migrations.
Run bin/rails zeitwerk:check early. It reports every file whose constant name does not match its path. Fix these before advancing config.load_defaults, or the app will not boot.
Pre-migration checklist
- Green test suite on the current Rails 6 version
- `bin/rails zeitwerk:check` reviewed and naming issues listed
- A dedicated upgrade branch and a database backup
Related paths
Official sources
Backs the breaking-change and migration-step claims.
Backs the breaking-change and migration-step claims.
Copy-ready AI prompts
Structured prompts for an AI coding assistant. Inspect first, then execute incrementally, and keep a human in the review loop.
You are helping upgrade a Ruby on Rails codebase from rails-6 to rails-7. Do not edit files yet. First inspect the repository and report: 1. The exact rails version in the Gemfile and Gemfile.lock, plus the Ruby version in .ruby-version and gemspec. 2. The current config.load_defaults value in config/application.rb. 3. Gems that may block the upgrade — run `bundle outdated` and flag anything unmaintained or version-pinned. 4. Custom autoloading patterns (require_dependency, non-conventional file/constant names) that Zeitwerk may reject. 5. The asset pipeline in use (Webpacker, Sprockets, jsbundling, importmap, Propshaft) and any deprecated config. 6. Pending and irreversible database migrations, plus the test and CI commands. Return: a risk summary, the files and gems most likely to break, a suggested upgrade order, the commands to run before editing, and any questions that need human confirmation.
Safety: Inspection only. The agent must not modify files, run migrations, or change the Gemfile in this step.
Works with Claude Code, Cursor, GitHub Copilot
Upgrade this Rails app from rails-6 to rails-7, one concern at a time. Work in this order and pause for review after each: (1) align the Ruby version if required, (2) bump the rails gem in the Gemfile and run `bundle update rails`, (3) run `bin/rails app:update` and review every prompted config diff (do not blindly overwrite), (4) resolve boot/autoload errors, (5) only after the suite is green, advance `config.load_defaults` to the new version and fix each deprecation it surfaces. After each step run `bin/rails test` (or the project's test command) and report results before continuing. Never run pending database migrations without explicit confirmation, and do not bundle unrelated refactors.
Safety: Apply changes incrementally and keep each step reviewable. Database migrations and config.load_defaults bumps require explicit human confirmation.
Works with Claude Code, Cursor, GitHub Copilot
Test plan
Commands
bundle exec rails testbundle exec rails test:systembundle exec rubocopbin/rails db:migrate:statusbin/rails assets:precompile
Manual checks
- Boot: run `bin/rails runner 'puts Rails.version'` and confirm the app boots without autoload errors.
- Background jobs: enqueue and process a job to confirm the queue adapter still works.
- Assets: load a page and confirm the asset pipeline serves CSS/JS with no 404s.
Regression risks
- Zeitwerk rejecting non-conventional file or constant names at boot.
- Deprecated framework defaults flipping behavior when config.load_defaults advances.
- Database migrations that are hard to roll back in production.
Acceptance criteria
- App boots and the full test suite passes on the target Rails version.
- No deprecation warnings remain after config.load_defaults is advanced.
- Assets precompile and background jobs process on the new adapters.