Spree Upgrades
Before writing code
Fetch live docs:
- Fetch https://spreecommerce.org/docs/developer/upgrades/quickstart for the canonical upgrade flow.
- Read the release notes for every minor between your current and target versions at https://github.com/spree/spree/releases.
- Cross-reference the announcement posts for each major (v5.0, v5.2, v5.4).
- Check the deprecated-gems list —
spree_auth_devise,deface,spree_backendare all archived. - Inspect your Gemfile +
gemfile.lockagainst the target Spree version'sspree.gemspec.
Conceptual Architecture
The Two Upgrade Shapes
| Path | Effort | Risk |
|---|---|---|
| v4.x → v5.0 | Major — admin rewrite, frontend removed, API restructure | High; plan as a project |
| v5.x → v5.y | Minor — Gemfile bump, migrations, regression test | Moderate |
| v5.y → v5.y+1 patch | Trivial — bundle update | Low |
What Changed v4 → v5
The biggest single jump in Spree's history:
- Admin rewritten in Tailwind + Hotwire (was Bootstrap + jQuery). All v4 admin customizations break.
- Legacy ERB frontend removed. Sites on
spree_frontendneed to migrate to the Next.js storefront orspree-rails-storefront. - Engines consolidated.
spree_backend,spree_frontend,spree_storefront_api_v2,spree_platform_apimerged into thespreeumbrella gem. spree_auth_devisedeprecated. v5 ships Devise auth in-core; old gem archived Feb 2026.- Deface deprecated. It only worked on the v4 ERB frontend.
- Metafields, Themes, Page Builder, CSV import/export added as new features.
- API v2 (JSON:API) is still available in v5.0–5.3 in core; extracted to
spree_legacy_api_v2in v5.4+.
What Changed v5.0 → v5.4
| Version | Headline change |
|---|---|
| v5.1 | Advanced rule-based promotions engine |
| v5.2 | create-spree-app CLI; Admin SDK; CSV importer overhaul; Tailwind 4 in storefront; spree_dev_tools gem; AI coding rules shipped |
| v5.3 | Price Lists for customer-segment overrides |
| v5.4 | API v3 (flat JSON, prefixed IDs, OpenAPI 3.0, 10× faster), @spree/sdk TypeScript SDK, Next.js 16 storefront, Payment Sessions, Markets, MeiliSearch integration, Webhooks 2.0, EU Omnibus 30-day price history, multi-arch Docker images, AGENTS.md |
Gemfile Pinning Strategy
# Pin per minor for predictability
gem 'spree', '~> 5.4' # accepts 5.4.0–5.4.99 patches
# Avoid
gem 'spree' # any 5.x — surprise breakage
gem 'spree', '5.4.2' # locks you to a patch; misses bug fixes
For extensions:
spec.add_dependency 'spree', '>= 5.4', '< 6.0'
Run bundle update spree to take patch releases.
Decorator Brittleness
Decorators (*_decorator.rb with prepend) are upgrade-fragile. When upgrading:
- Audit every decorator — does the decorated method still exist? Same signature?
- Run the test suite after the version bump
- Watch for
NoMethodErrorinsuper— the underlying method was renamed - Watch for new validations — your decorator may conflict with new core rules
Reduce risk by preferring events and dependencies over decorators (see spree-extensions skill).
Deprecated Gems to Remove
| Gem | Action |
|---|---|
spree_auth_devise | Remove; archived. v5 has built-in auth. |
spree_backend | Remove; replaced by Tailwind admin in spree umbrella. |
spree_frontend | Remove; replaced by Next.js storefront or spree-rails-storefront. |
deface | Remove when fully off the ERB frontend. Use partial slots in v5 admin. |
spree_api (separate gem) | Remove; now in spree umbrella. |
spree_storefront_api_v2 (separate gem) | Remove; either bundled or use spree_legacy_api_v2. |
spree_platform_api (separate gem) | Remove; same. |
API v2 → v3 Migration
Side-by-side strategy:
- v5.4+ project includes both
/api/v3/(built-in) and/api/v2/(viaspree_legacy_api_v2) - Build new clients on v3
- Migrate existing clients one surface at a time
- Monitor v2 traffic; sunset after N weeks of zero usage
- Eventually remove
spree_legacy_api_v2from Gemfile
Admin Customization Migration
- Deface overrides → translate to partial injection slots OR opt out (often the slot system is sufficient)
- Bootstrap CSS → translate to Tailwind classes (use the Spree v5 admin views as reference)
- Custom admin layouts → re-implement against v5's Tailwind/Hotwire base layout
- jQuery code → port to Stimulus controllers
Storefront Migration
- Legacy ERB frontend → either:
- Fork
spree/storefront(Next.js) and migrate over weeks - Use
spree-rails-storefront(Tailwind page-builder ERB storefront) for minimal change
- Fork
Plan as a separate project, not a Gemfile bump.
Implementation Guidance
Pre-Upgrade Audit
Before changing the Gemfile:
- Inventory decorators —
grep -r '_decorator.rb' app/andgrep -r '.prepend(' app/ - Inventory Deface overrides —
grep -r 'Deface::Override' app/ - Inventory custom admin views —
find app/views/spree/admin -name '*.erb' - Inventory custom controllers —
find app/controllers/spree -name '*.rb' - Inventory subscribers —
find app/subscribers -name '*.rb' - Inventory custom payment methods, calculators, services
- Map all current Gemfile entries to their v5 fate (kept / removed / replaced)
- List all third-party Spree extensions — verify each has v5 support
Upgrade Workflow (v5.x to v5.y)
# 1. Branch
git checkout -b upgrade-spree-5.x
# 2. Bump
bundle update spree spree_admin spree_emails
# 3. Run migrations
bin/rails db:migrate
# 4. Run specs
bundle exec rspec
# 5. Smoke test admin + storefront
bin/rails server
# manually browse, place a test order
# 6. Deploy to staging
# run a fuller regression suite
# 7. Deploy to prod
Upgrade Workflow (v4 → v5) — Project-Sized
- Stand up a parallel v5 environment with same data (use
db/structure.sqlimport + data export) - Migrate decorators one model at a time
- Migrate admin customizations to partial slots / new conventions
- Choose storefront path — Next.js (highest-fidelity for modern UX) or
spree-rails-storefront(least change) - Migrate frontend — this is often 50%+ of the project
- Migrate payment integrations — install v5-compatible gateway gems
- Cutover plan — data migration, DNS switch, monitoring
Rolling Back
- Always tag the release before deploying
- Database migrations: design backward-compatible (additive only; drops in a later release)
- Rolling deploy with multiple pods lets you halt mid-deploy if alerts fire
- DB rollback is a last resort —
bin/rails db:rollbackonly works if migrations are reversible
Test Coverage as Upgrade Insurance
Before upgrading:
- System specs covering: cart → checkout → order placement
- API specs for every consumer-facing v3 endpoint
- Subscriber specs for each event you handle
- Decorator specs for each model decoration
If coverage is thin, write tests first, then upgrade. The cost of bad coverage during an upgrade is far higher than the cost of writing tests.
Common Upgrade Pitfalls
- Skipping minors — v5.0 → v5.4 in one jump misses the v5.2 generator changes that interact with v5.3 PriceList. Step through.
- Decorator
supercalls a method that no longer exists — manifests asNoMethodErrorat runtime, not boot. - Removed admin views referenced by Deface — Deface silently no-ops; visual regression.
- API v2 client breakage when removing the legacy gem — confirm zero v2 traffic for weeks before removal.
- Payment gateway gem behind on Spree compatibility — verify each gem supports the target Spree before bumping.
- Sidekiq queue names changed — webhook delivery queue renamed in some minor; check release notes.
- **Migratio