Sets up and manages dual-boot Ruby and Rails environments using the next_rails gem. Helps configure Gemfile for running two versions of Rails, Ruby, or any core dependency simultaneously, set up CI for both versions, use NextRails.next? for version-dependent code, and clean up after the upgrade is complete. Based on FastRuby.io methodology and "The Complete Guide to Upgrade Rails" ebook.
Installs into .claude/skills of the current project.
Are you the author of Dual Boot?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/ombulabs-dual-boot)
---
name: dual-boot
description: Sets up and manages dual-boot Ruby and Rails environments using the next_rails gem. Helps configure Gemfile for running two versions of Rails, Ruby, or any core dependency simultaneously, set up CI for both versions, use NextRails.next? for version-dependent code, and clean up after the upgrade is complete. Based on FastRuby.io methodology and "The Complete Guide to Upgrade Rails" ebook.
argument-hint: "[current-version] [target-version]"
---
When invoked via `/dual-boot`, follow the setup workflow in `workflows/setup-workflow.md` to set up dual-boot for this project. If the user provides version arguments (e.g. `/dual-boot 7.0 7.1`), use them as the current and target versions. If no arguments are provided, detect the current version from the Gemfile and ask the user for the target version.
# Dual-Boot Skill
- **Purpose:** Set up and manage dual-boot environments for Rails, Ruby, or core Gemfile dependencies using the `next_rails` gem
- **Key Gem:** [next_rails](https://github.com/fastruby/next_rails)
- **Methodology:** Based on FastRuby.io upgrade best practices and "The Complete Guide to Upgrade Rails" ebook
- **Attribution:** Content based on "The Complete Guide to Upgrade Rails" by FastRuby.io (OmbuLabs)
---
## Overview
Dual-booting allows a Ruby application to maintain two sets of dependencies simultaneously. While most commonly used for **Rails version upgrades**, the same approach works for upgrading **Ruby versions** or any **core dependency** in your Gemfile (e.g., `sidekiq`, `devise`, `pg`).
This skill helps you:
- **Set up** dual-boot with the `next_rails` gem
- **Configure** the Gemfile to support two versions of Rails, Ruby, or other key dependencies
- **Branch** application code using `NextRails.next?`
- **Configure CI** to test against both dependency sets
- **Clean up** dual-boot code after the upgrade is complete
---
## CRITICAL: Always Use `NextRails.next?` — Never Use Feature Detection
When code would break on one version and needs a different implementation on the other, **always use `NextRails.next?`** from the `next_rails` gem to branch — never feature detection. Do not use `respond_to?`, `defined?`, `const_defined?`, or any other feature-detection pattern for version branching.
**Why feature detection is problematic:**
- **Hard to understand:** readers must know which version introduced a method or constant to grasp the intent
- **Hard to maintain:** `respond_to?` / `defined?` checks pile up and become impossible to clean up because their purpose is lost
- **Fragile:** may give wrong results if gems monkey-patch methods or constants in or out
- **Obscures intent:** the code says "does this exist?" when it means "are we on the next Rails version?"
**Why `NextRails.next?` is better:**
- **Explicit and readable:** anyone reading the code immediately understands "this branch is for the next version"
- **Easy to clean up:** after the upgrade, search for `NextRails.next?` and remove all branches
- **The standard:** established dual-boot mechanism in the FastRuby.io methodology
### Pattern
Reach for `NextRails.next?` only when the old and new APIs are genuinely **two-sided** — the old one raises on the next version and the new one doesn't exist on the current version. A plain deprecation warning is *not* a reason to branch: if the new API works on both sides, migrate the call site directly.
❌ **WRONG — Do NOT use feature detection (`respond_to?`, `defined?`, etc.):**
```ruby
test_request =
if ActionController::TestRequest.respond_to?(:create)
ActionController::TestRequest.create
else
ActionController::TestRequest.new
end
```
✅ **CORRECT — Use `NextRails.next?`:**
```ruby
test_request =
if NextRails.next?
ActionController::TestRequest.create
else
ActionController::TestRequest.new
end
```
This is a genuine two-sided case (Rails 4.2 → 5.0). On 4.2, [`ActionController::TestRequest.new`](https://github.com/rails/rails/blob/11f2bdf75a888682b34df0f9be03b94f54fc6796/actionpack/lib/action_controller/test_case.rb#L201) takes an optional `env`; on 5.0 `new` [requires two non-optional arguments](https://github.com/rails/rails/blob/c4d3e202e10ae627b3b9c34498afb45450652421/actionpack/lib/action_controller/test_case.rb#L48) so the 4.2 call fails. Rails 5.0 introduces `TestRequest.create`, which does not exist on 4.2 — so each side raises on the other.
Put the next-version branch on top so cleanup is mechanical: after the upgrade, keep the `if` body and drop the `else`. See `references/code-patterns.md` for more examples.
### When to Apply
Use `NextRails.next?` branching for:
- **Removed methods or constants** where the replacement only exists on the new side (e.g., a gem-provided method replaced by a native Rails method with different syntax)
- **Incompatible signature or return-type changes** where the old and new forms genuinely fail on opposite sides
- **Gem version differences** where the gem's API is different across versions pinned to each Rails version
- **Initializer changes** where a config or middleware raises on one side
- **Ruby version differences** (e.g., syntax changes, stdlib removals)
**Not a reason to branch:** plain deprecation warnings. If the new API works on both versions (e.g. `config.fixture_path=` → `config.fixture_paths=`, `update_attributes` → `update` before its removal), migrate the call site directly — do not wrap it in `NextRails.next?`. See `references/code-patterns.md` "When NOT to Branch: Deprecations".
---
## Trigger Patterns
Claude should activate this skill when user says:
- "Set up dual boot for my Rails app"
- "Help me dual-boot Rails [x] and [y]"
- "Dual-boot Ruby [x] and [y]"
- "Set up dual boot for upgrading [dependency]"
- "Add next_rails to my project"
- "Configure dual-boot CI"
- "Clean up dual-boot code"
- "Remove next_rails after upgrade"
- "How do I use NextRails.next?"
- "Set up Gemfile for two Rails versions"
- "Set up Gemfile for two Ruby versions"
---
## Core Workflows
### Workflow 1: Set Up Dual-Boot
See `workflows/setup-workflow.md` for the complete step-by-step process.
**Summary:**
0. Verify deprecation warnings are not silenced (see `references/deprecation-tracking.md`)
1. Check if dual-boot is already set up (look for `Gemfile.next`)
2. Add `next_rails` gem to Gemfile
3. Run `bundle install`
4. Run `next_rails --init` (only if `Gemfile.next` does NOT exist)
5. Configure Gemfile with `next?` conditionals for the dependency being upgraded
6. Install dependencies for both versions:
- Current: `bundle install`
- Next: `cp Gemfile.lock Gemfile.next.lock && BUNDLE_GEMFILE=Gemfile.next bundle install`
7. Verify both versions work
### Workflow 2: Add Version-Dependent Code
When proposing code changes that need to work with both dependency sets:
1. Verify `next_rails` is set up (check for `Gemfile.next`)
2. Use `NextRails.next?` for branching — never `respond_to?`
3. Keep the `next?` branch (new version code) on top
4. Keep the `else` branch (old version code) below
See `references/code-patterns.md` for examples.
### Workflow 3: Configure CI
See `references/ci-configuration.md` for CI setup with GitHub Actions, CircleCI, and Jenkins.
### Workflow 4: Clean Up After Upgrade
See `workflows/cleanup-workflow.md` for the complete post-upgrade cleanup process.
**Summary:**
1. Search for all `NextRails.next?` references
2. Keep only the `NextRails.next?` (true) branch code
3. Remove all `else` branches
4. Remove `next?` method from Gemfile
5. Remove `next_rails` gem if no longer needed
6. Remove `Gemfile.next` and replace `Gemfile.lock` with `Gemfile.next.lock`
7. Update CI to remove dual-boot configuration
8. Run full test suite
9. Commit cleanup changes
---
## Available Resources
### Core Documentation
- `SKILL.md` - This file (entry point)
### Reference Materials
- `references/deprecation-tracking.md` - Detecting silenced deprecations and configuring tracking (Rails 3.0+)
- `references/code-patterns.md` - `NextRails.next?` usage examples in application code
- `references/ci-configuration.md` - CI setup for dual-boot (GitHub Actions, CircleCI, Jenkins)
- `references/gemfile-examples.md` - Gemfile configuration patterns for dual-boot
### Workflows
- `workflows/setup-workflow.md` - Step-by-step dual-boot setup
- `workflows/cleanup-workflow.md` - Post-upgrade dual-boot removal
### Examples
- `examples/basic-setup.md` - Basic dual-boot setup example
---
## Key Principles
1. **Ensure deprecation warnings are visible** — silenced deprecations mean you can't track upgrade progress
2. **Never run `next_rails --init` if `Gemfile.next` exists** — it will duplicate the `next?` method
3. **Always use `NextRails.next?` for version-dependent code** — never `respond_to?`
4. **Test both versions using the project's own test runner.** Detect it before running anything: check the `Gemfile` for `rspec-rails`, `parallel_tests`, `turbo_tests`, or `minitest-parallel_fork`, check whether the app has `spec/` or `test/`, and prefer wrappers like `bin/test` when they exist. Every `bundle exec rspec` in the workflows, examples, and CI reference is illustrative; substitute the detected command (e.g. `bin/rails test`, `bundle exec parallel_rspec spec/`, `bin/test`) and prefix with `BUNDLE_GEMFILE=Gemfile.next` (or the `next` CLI) to run it against the next dependency set.
5. **Clean up after upgrade** — search for and remove all `NextRails.next?` branches
6. **Add `next_rails` at the Gemfile root level** — not inside a `:development` or `:test` group
---
## Quick Reference
| Command | Purpose |
|---------|---------|
| `next_rails --init` | Initialize dual-boot (creates `Gemfile.next` symlink) |
| `next bundle install` | Install gems for the next dependency set |
| `next bundle exec rspec` | Run tests with the next dependency set |
| `BUNDLE_GEMFILE=Gemfile.next bundle exec rails server` | Start server with next version |
| `BUNDLE_GEMFILE=Gemfile.next bundle exec rspec` | Alternative to `next` command |
---
See [CHANGELOG.md](CHANGELOG.md) for version history and current version.