Summary
Project Daedalus is running several end-of-life or significantly outdated dependencies that should be upgraded for security, performance, and long-term maintainability. Rails 7.1 reached end-of-life in October 2025 and is no longer receiving security patches. This issue documents every outdated dependency, what needs to change, and a recommended upgrade path.
Current State vs Latest Versions
| Dependency |
Current |
Latest |
Severity |
| Ruby |
3.4.8 |
4.0.2 |
⚠️ Major version jump |
| Rails |
~> 7.1 |
8.1.3 |
🔴 EOL — no security patches |
| google-cloud-firestore |
~> 2.8 |
3.1.1 |
⚠️ Major version jump |
| tailwindcss-rails |
~> 2.0 |
4.x (Tailwind v4) |
⚠️ Major rewrite |
| puma |
~> 6.0 |
6.6.1 (safe) / 7.2.0 |
✅ Patch safe |
| propshaft |
unpinned |
1.3.1 |
✅ Likely fine |
| sqlite3 |
~> 1.4 |
2.x+ |
⚠️ May need bump |
Recommended Upgrade Path
The safest approach is incremental. Do NOT jump straight to Rails 8.1 — each step has config changes and deprecation removals that need to be handled individually.
Phase 1: Rails 7.1 → 7.2 (Smallest, safest step)
Priority: HIGH — gets us off EOL onto a supported version
Config Changes Required:
config.cache_classes = true → config.enable_reloading = false (production.rb)
config.active_record.dump_schema_after_migration = false — can be removed (not using ActiveRecord)
config.active_storage.service = :google — review if Active Storage is actually used
- Run
rails app:update to regenerate config files and review diffs
- Update
config.load_defaults from 7.1 to 7.2 in config/application.rb
Gemfile Changes:
Breaking Changes to Watch For:
- Removed deprecated
@rails/ujs (project uses Turbo so this should be fine)
- Removed deprecated behavior for transaction blocks using
return/break/throw (not applicable — no ActiveRecord)
- Serialization: public signature for
serialize method changed (not applicable — Firestore models don't use AR serialize)
What's Safe:
Most 7.1 → 7.2 breaking changes are ActiveRecord-related. Since this project uses Firestore with ActiveModel (not ActiveRecord), the majority of breaking changes don't apply. This is the easiest upgrade step.
Phase 2: Rails 7.2 → 8.0
Key Changes:
- Requires Ruby 3.2+ (we're on 3.4.8 so this is fine)
config.load_defaults → 8.0
Regexp.timeout set to 1s by default — check the search regex in mods_controller.rb (find_mods method uses Regexp.escape so should be fine)
- Schema sorting changes (not applicable — no ActiveRecord schema)
- New default authentication generator available (optional)
Gemfile Changes:
What's Safe:
Again, most breaking changes are ActiveRecord-focused. The controller/view layer is largely compatible.
Phase 3: Rails 8.0 → 8.1
Key Changes:
- Removed support for semicolons as query string separator
- Removed deprecated
bin/rake stats
config.load_defaults → 8.1
What's Safe:
Smallest set of breaking changes. Mostly cleanup of previously deprecated features. This is the least risky step in the entire upgrade path — no database, serialization, or middleware changes to worry about.
Phase 4: Ruby 3.4 → 4.0 (Optional, can be deferred)
Priority: LOW — Ruby 3.4 is still supported
Breaking Changes:
*nil no longer calls nil.to_a (returns empty array directly) — unlikely to affect this project
- Ractor API completely revised (not used in this project)
- Binary extensions must be rebuilt (handled by
bundle install)
Set and Pathname are now core classes (no longer need require)
What to Update:
.ruby-version → 4.0.2
Gemfile → ruby "4.0.2"
Dockerfile → FROM ruby:4.0-bookworm
- Verify all gems are Ruby 4.0 compatible before upgrading
Recommendation:
Wait until Rails 8.x officially supports Ruby 4.0 and all gem dependencies have confirmed compatibility. Ruby 3.4 is still receiving security patches.
Phase 5: google-cloud-firestore 2.x → 3.x
Priority: MEDIUM
Breaking Changes:
- Default return value of
Client#transaction changed — now returns value of yielded block
- Low-level V1 module classes renamed
- Client constructor now takes configuration block instead of keyword arguments
What to Check:
Firestorable concern — verify Google::Cloud::Firestore.new(credentials: credentials.to_h) still works with v3 API
firestore.col("mods").get and firestore.col("tools").get — verify collection query API hasn't changed
- Test thoroughly — Firestore is the backbone of the entire app
Gemfile Changes:
gem "google-cloud-firestore", "~> 3.1"
Phase 6: tailwindcss-rails 2.x → 4.x (Tailwind CSS v3 → v4)
Priority: LOW — can stay on v3 indefinitely
This is the Riskiest Upgrade
Tailwind CSS v4 is a complete rewrite:
- JavaScript config (
tailwind.config.js) replaced with CSS-based config using @theme
@tailwind base/components/utilities directives replaced with @import "tailwindcss"
- PostCSS removed, replaced with LightningCSS
- Default values changed:
ring width 3px → 1px, ring color blue-500 → currentColor, border-* defaults gray-200 → currentColor
- Content detection is now automatic
What Would Break:
config/tailwind.config.js — entire file needs rewriting to CSS-based @theme format
- Every
ring, border, divide utility — defaults changed, may need explicit values
- Custom
icarus color palette — needs migration to @theme format
- Custom
topo-light/topo-dark background images — need migration to @theme
- All dark mode classes — should still work but need testing
Recommendation:
Defer this upgrade. Tailwind CSS v3 with tailwindcss-rails v2 is stable and will continue to work. The migration is extensive and touches every view file. Only upgrade when there's a compelling reason (v3 security issue, needed v4 feature, etc.).
Dockerfile Updates
The Dockerfile will need updating alongside the Ruby/Rails upgrades:
# Phase 1-3 (Rails upgrade only):
FROM ruby:3.4-bookworm AS build
# No change needed
# Phase 4 (Ruby 4.0):
FROM ruby:4.0-bookworm AS build
Testing Strategy
Since the app uses Firestore (not a local database), testing upgrades requires:
- Local testing with Firestore credentials — essential before deploying any upgrade
- Run
bundle exec rspec after each phase to catch regressions
- Check all pages manually — Home, Mods (index + show), Tools, Info
- Verify Firestore reads — mods listing, tools listing, search, author filtering
- Verify downloads — Stimulus controller
mods#download still triggers correctly
- Check asset pipeline — Propshaft compiles CSS/JS/images correctly
- Docker build test —
docker build . succeeds and container starts
Quick Wins (No Risk)
These can be done right now without any upgrade:
- Puma: Already on
~> 6.0, latest 6.x is 6.6.1. Just bundle update puma — bug fixes only.
- Propshaft: Unpinned, so
bundle update propshaft gets latest 1.3.1 — safe.
- Remove unused ActiveRecord config: The production.rb has
config.active_record.dump_schema_after_migration = false but the app doesn't use ActiveRecord. Can be removed for clarity.
Summary of Priorities
- 🔴 Rails 7.1 → 7.2 — Get off EOL. Mostly config changes. Low risk for this project.
- 🟡 Rails 7.2 → 8.0 — Incremental step. Low risk.
- 🟡 Rails 8.0 → 8.1 — Small step. Low risk.
- 🟡 google-cloud-firestore 2.x → 3.x — Test Firestore concern carefully.
- 🟢 Ruby 4.0 — Defer until ecosystem matures.
- 🟢 Tailwind v4 — Defer. V3 is fine.
Summary
Project Daedalus is running several end-of-life or significantly outdated dependencies that should be upgraded for security, performance, and long-term maintainability. Rails 7.1 reached end-of-life in October 2025 and is no longer receiving security patches. This issue documents every outdated dependency, what needs to change, and a recommended upgrade path.
Current State vs Latest Versions
Recommended Upgrade Path
The safest approach is incremental. Do NOT jump straight to Rails 8.1 — each step has config changes and deprecation removals that need to be handled individually.
Phase 1: Rails 7.1 → 7.2 (Smallest, safest step)
Priority: HIGH — gets us off EOL onto a supported version
Config Changes Required:
config.cache_classes = true→config.enable_reloading = false(production.rb)config.active_record.dump_schema_after_migration = false— can be removed (not using ActiveRecord)config.active_storage.service = :google— review if Active Storage is actually usedrails app:updateto regenerate config files and review diffsconfig.load_defaultsfrom7.1to7.2inconfig/application.rbGemfile Changes:
Breaking Changes to Watch For:
@rails/ujs(project uses Turbo so this should be fine)return/break/throw(not applicable — no ActiveRecord)serializemethod changed (not applicable — Firestore models don't use AR serialize)What's Safe:
Most 7.1 → 7.2 breaking changes are ActiveRecord-related. Since this project uses Firestore with ActiveModel (not ActiveRecord), the majority of breaking changes don't apply. This is the easiest upgrade step.
Phase 2: Rails 7.2 → 8.0
Key Changes:
config.load_defaults→8.0Regexp.timeoutset to 1s by default — check the search regex inmods_controller.rb(find_modsmethod usesRegexp.escapeso should be fine)Gemfile Changes:
What's Safe:
Again, most breaking changes are ActiveRecord-focused. The controller/view layer is largely compatible.
Phase 3: Rails 8.0 → 8.1
Key Changes:
bin/rake statsconfig.load_defaults→8.1What's Safe:
Smallest set of breaking changes. Mostly cleanup of previously deprecated features. This is the least risky step in the entire upgrade path — no database, serialization, or middleware changes to worry about.
Phase 4: Ruby 3.4 → 4.0 (Optional, can be deferred)
Priority: LOW — Ruby 3.4 is still supported
Breaking Changes:
*nilno longer callsnil.to_a(returns empty array directly) — unlikely to affect this projectbundle install)SetandPathnameare now core classes (no longer needrequire)What to Update:
.ruby-version→4.0.2Gemfile→ruby "4.0.2"Dockerfile→FROM ruby:4.0-bookwormRecommendation:
Wait until Rails 8.x officially supports Ruby 4.0 and all gem dependencies have confirmed compatibility. Ruby 3.4 is still receiving security patches.
Phase 5: google-cloud-firestore 2.x → 3.x
Priority: MEDIUM
Breaking Changes:
Client#transactionchanged — now returns value of yielded blockWhat to Check:
Firestorableconcern — verifyGoogle::Cloud::Firestore.new(credentials: credentials.to_h)still works with v3 APIfirestore.col("mods").getandfirestore.col("tools").get— verify collection query API hasn't changedGemfile Changes:
Phase 6: tailwindcss-rails 2.x → 4.x (Tailwind CSS v3 → v4)
Priority: LOW — can stay on v3 indefinitely
This is the Riskiest Upgrade
Tailwind CSS v4 is a complete rewrite:
tailwind.config.js) replaced with CSS-based config using@theme@tailwind base/components/utilitiesdirectives replaced with@import "tailwindcss"ringwidth 3px → 1px,ringcolor blue-500 → currentColor,border-*defaults gray-200 → currentColorWhat Would Break:
config/tailwind.config.js— entire file needs rewriting to CSS-based@themeformatring,border,divideutility — defaults changed, may need explicit valuesicaruscolor palette — needs migration to@themeformattopo-light/topo-darkbackground images — need migration to@themeRecommendation:
Defer this upgrade. Tailwind CSS v3 with tailwindcss-rails v2 is stable and will continue to work. The migration is extensive and touches every view file. Only upgrade when there's a compelling reason (v3 security issue, needed v4 feature, etc.).
Dockerfile Updates
The Dockerfile will need updating alongside the Ruby/Rails upgrades:
Testing Strategy
Since the app uses Firestore (not a local database), testing upgrades requires:
bundle exec rspecafter each phase to catch regressionsmods#downloadstill triggers correctlydocker build .succeeds and container startsQuick Wins (No Risk)
These can be done right now without any upgrade:
~> 6.0, latest 6.x is 6.6.1. Justbundle update puma— bug fixes only.bundle update propshaftgets latest 1.3.1 — safe.config.active_record.dump_schema_after_migration = falsebut the app doesn't use ActiveRecord. Can be removed for clarity.Summary of Priorities