| name | spree-upgrades |
| description | Upgrade a Spree application — version-to-version migration paths (v4 → v5 is a major rewrite; v5.x → v5.y are simpler), Gemfile pinning strategy, decorator brittleness across versions, deprecated gems to remove (`spree_auth_devise`, `deface`, `spree_backend`), API v2 → v3 migration via `spree_legacy_api_v2`, admin Bootstrap → Tailwind transition, the upgrade guide workflow, and rollback strategy. Use when planning a Spree upgrade or auditing technical debt blocking one.
|
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_backend are all archived.
- Inspect your Gemfile +
gemfile.lock against the target Spree version's spree.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_frontend need to migrate to the Next.js storefront or spree-rails-storefront.
- Engines consolidated.
spree_backend, spree_frontend, spree_storefront_api_v2, spree_platform_api merged into the spree umbrella gem.
spree_auth_devise deprecated. 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_v2 in 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
gem 'spree', '~> 5.4'
gem 'spree'
gem 'spree', '5.4.2'
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
NoMethodError in super — 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/ (via spree_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_v2 from 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
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/ and grep -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)
git checkout -b upgrade-spree-5.x
bundle update spree spree_admin spree_emails
bin/rails db:migrate
bundle exec rspec
bin/rails server
Upgrade Workflow (v4 → v5) — Project-Sized
- Stand up a parallel v5 environment with same data (use
db/structure.sql import + 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:rollback only 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
super calls a method that no longer exists — manifests as NoMethodError at 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.
- Migrations slow on large tables —
add_column on a 50M-row spree_orders can lock. Use algorithm: :concurrently for indexes.
- Tailwind 4 upgrade missed — v5 admin requires Tailwind 4; v3 syntax doesn't compile.
- Importmap pinning out of date — old JS pins resolve to missing modules.
config/credentials.yml.enc re-encryption required when Rails version bumps include encryption-format changes.
Always read every minor release note from current to target before kicking off — even single-minor upgrades can have caveats hidden in the notes.