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
# 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
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)
# 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.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.
1---2name: spree-upgrades3description: 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.4---56# Spree Upgrades78## Before writing code910**Fetch live docs**:111. Fetch https://spreecommerce.org/docs/developer/upgrades/quickstart for the canonical upgrade flow.122. Read the release notes for **every minor** between your current and target versions at https://github.com/spree/spree/releases.133. Cross-reference the announcement posts for each major (v5.0, v5.2, v5.4).144. Check the deprecated-gems list — `spree_auth_devise`, `deface`, `spree_backend` are all archived.155. Inspect your Gemfile + `gemfile.lock` against the target Spree version's `spree.gemspec`.1617## Conceptual Architecture1819### The Two Upgrade Shapes2021| Path | Effort | Risk |22|------|--------|------|23| **v4.x → v5.0** | **Major** — admin rewrite, frontend removed, API restructure | High; plan as a project |24| **v5.x → v5.y** | Minor — Gemfile bump, migrations, regression test | Moderate |25| **v5.y → v5.y+1 patch** | Trivial — bundle update | Low |2627### What Changed v4 → v52829The biggest single jump in Spree's history:30- **Admin rewritten** in Tailwind + Hotwire (was Bootstrap + jQuery). All v4 admin customizations break.31- **Legacy ERB frontend removed.** Sites on `spree_frontend` need to migrate to the Next.js storefront or `spree-rails-storefront`.32- **Engines consolidated.** `spree_backend`, `spree_frontend`, `spree_storefront_api_v2`, `spree_platform_api` merged into the `spree` umbrella gem.33- **`spree_auth_devise` deprecated.** v5 ships Devise auth in-core; old gem archived Feb 2026.34- **Deface deprecated.** It only worked on the v4 ERB frontend.35- **Metafields, Themes, Page Builder, CSV import/export added** as new features.36- **API v2 (JSON:API)** is still available in v5.0–5.3 in core; extracted to `spree_legacy_api_v2` in v5.4+.3738### What Changed v5.0 → v5.43940| Version | Headline change |41|---------|----------------|42| **v5.1** | Advanced rule-based promotions engine |43| **v5.2** | `create-spree-app` CLI; Admin SDK; CSV importer overhaul; Tailwind 4 in storefront; `spree_dev_tools` gem; AI coding rules shipped |44| **v5.3** | Price Lists for customer-segment overrides |45| **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 |4647### Gemfile Pinning Strategy4849```ruby50# Pin per minor for predictability51gem 'spree', '~> 5.4' # accepts 5.4.0–5.4.99 patches52# Avoid53gem 'spree' # any 5.x — surprise breakage54gem 'spree', '5.4.2' # locks you to a patch; misses bug fixes55```5657For extensions:58```ruby59spec.add_dependency 'spree', '>= 5.4', '< 6.0'60```6162Run `bundle update spree` to take patch releases.6364### Decorator Brittleness6566Decorators (`*_decorator.rb` with `prepend`) are upgrade-fragile. When upgrading:671. **Audit every decorator** — does the decorated method still exist? Same signature?682. **Run the test suite** after the version bump693. **Watch for `NoMethodError` in `super`** — the underlying method was renamed704. **Watch for new validations** — your decorator may conflict with new core rules7172Reduce risk by preferring **events** and **dependencies** over decorators (see `spree-extensions` skill).7374### Deprecated Gems to Remove7576| Gem | Action |77|-----|--------|78| `spree_auth_devise` | **Remove**; archived. v5 has built-in auth. |79| `spree_backend` | **Remove**; replaced by Tailwind admin in `spree` umbrella. |80| `spree_frontend` | **Remove**; replaced by Next.js storefront or `spree-rails-storefront`. |81| `deface` | **Remove** when fully off the ERB frontend. Use partial slots in v5 admin. |82| `spree_api` (separate gem) | **Remove**; now in `spree` umbrella. |83| `spree_storefront_api_v2` (separate gem) | **Remove**; either bundled or use `spree_legacy_api_v2`. |84| `spree_platform_api` (separate gem) | **Remove**; same. |8586### API v2 → v3 Migration8788Side-by-side strategy:891. v5.4+ project includes both `/api/v3/` (built-in) and `/api/v2/` (via `spree_legacy_api_v2`)902. Build new clients on v3913. Migrate existing clients one surface at a time924. Monitor v2 traffic; sunset after N weeks of zero usage935. Eventually remove `spree_legacy_api_v2` from Gemfile9495### Admin Customization Migration9697- **Deface overrides** → translate to partial injection slots OR opt out (often the slot system is sufficient)98- **Bootstrap CSS** → translate to Tailwind classes (use the Spree v5 admin views as reference)99- **Custom admin layouts** → re-implement against v5's Tailwind/Hotwire base layout100- **jQuery code** → port to Stimulus controllers101102### Storefront Migration103104- **Legacy ERB frontend** → either:105 - Fork `spree/storefront` (Next.js) and migrate over weeks106 - Use `spree-rails-storefront` (Tailwind page-builder ERB storefront) for minimal change107108Plan as a separate project, not a Gemfile bump.109110## Implementation Guidance111112### Pre-Upgrade Audit113114Before changing the Gemfile:1151161. **Inventory decorators** — `grep -r '_decorator.rb' app/` and `grep -r '.prepend(' app/`1172. **Inventory Deface overrides** — `grep -r 'Deface::Override' app/`1183. **Inventory custom admin views** — `find app/views/spree/admin -name '*.erb'`1194. **Inventory custom controllers** — `find app/controllers/spree -name '*.rb'`1205. **Inventory subscribers** — `find app/subscribers -name '*.rb'`1216. **Inventory custom payment methods, calculators, services**1227. **Map all current Gemfile entries** to their v5 fate (kept / removed / replaced)1238. **List all third-party Spree extensions** — verify each has v5 support124125### Upgrade Workflow (v5.x to v5.y)126127```bash128# 1. Branch129git checkout -b upgrade-spree-5.x130131# 2. Bump132bundle update spree spree_admin spree_emails133134# 3. Run migrations135bin/rails db:migrate136137# 4. Run specs138bundle exec rspec139140# 5. Smoke test admin + storefront141bin/rails server142# manually browse, place a test order143144# 6. Deploy to staging145# run a fuller regression suite146147# 7. Deploy to prod148```149150### Upgrade Workflow (v4 → v5) — Project-Sized1511521. **Stand up a parallel v5 environment** with same data (use `db/structure.sql` import + data export)1532. **Migrate decorators** one model at a time1543. **Migrate admin customizations** to partial slots / new conventions1554. **Choose storefront path** — Next.js (highest-fidelity for modern UX) or `spree-rails-storefront` (least change)1565. **Migrate frontend** — this is often 50%+ of the project1576. **Migrate payment integrations** — install v5-compatible gateway gems1587. **Cutover plan** — data migration, DNS switch, monitoring159160### Rolling Back161162- **Always tag the release** before deploying163- **Database migrations**: design backward-compatible (additive only; drops in a later release)164- **Rolling deploy with multiple pods** lets you halt mid-deploy if alerts fire165- **DB rollback** is a last resort — `bin/rails db:rollback` only works if migrations are reversible166167### Test Coverage as Upgrade Insurance168169Before upgrading:170- **System specs** covering: cart → checkout → order placement171- **API specs** for every consumer-facing v3 endpoint172- **Subscriber specs** for each event you handle173- **Decorator specs** for each model decoration174175If 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.176177### Common Upgrade Pitfalls178179- **Skipping minors** — v5.0 → v5.4 in one jump misses the v5.2 generator changes that interact with v5.3 PriceList. Step through.180- **Decorator `super` calls a method that no longer exists** — manifests as `NoMethodError` at runtime, not boot.181- **Removed admin views referenced by Deface** — Deface silently no-ops; visual regression.182- **API v2 client breakage when removing the legacy gem** — confirm zero v2 traffic for weeks before removal.183- **Payment gateway gem behind on Spree compatibility** — verify each gem supports the target Spree before bumping.184- **Sidekiq queue names changed** — webhook delivery queue renamed in some minor; check release notes.185- **Migrations slow on large tables** — `add_column` on a 50M-row `spree_orders` can lock. Use `algorithm: :concurrently` for indexes.186- **Tailwind 4 upgrade missed** — v5 admin requires Tailwind 4; v3 syntax doesn't compile.187- **Importmap pinning out of date** — old JS pins resolve to missing modules.188- **`config/credentials.yml.enc` re-encryption** required when Rails version bumps include encryption-format changes.189190Always read **every** minor release note from current to target before kicking off — even single-minor upgrades can have caveats hidden in the notes.