F. Version Standardization Assessment
Node Version Overview
| Repo | Current | Status | Target |
|---|---|---|---|
| reverb-react | ~10.15.3 | ⛔ EOL Dec 2020 | Modernize → Next.js 16 + Node 24 |
| reverb-backend | 14.17.3 | 🔴 EOL Apr 2023 | → 20 → 22 → 24 |
| soreto-zoe | 16.13.0 | 🔴 EOL Sep 2023 | → 18 → 20 → 22 → 24 |
| soreto-melissa | 22.0.0 | ⚠️ Maintenance LTS | Upgrade → 24 |
Recommended target: Node 24 LTS (Active LTS as of May 2026; Node 22 is Maintenance LTS, Node 26 is Current/unstable — not yet LTS).
Node Upgrade Paths
reverb-react: Modernize to Next.js 16 + Node 24
The objective is to modernize reverb-react to a current stack — not to freeze and retire it. The existing stack (Babel 6, Webpack 4, Node 10, React 17/dom 16.5 mismatch, react-router@3 + react-router-dom@4 mismatch) cannot be incrementally upgraded; the gaps are too large. The correct approach is a controlled rewrite to Next.js 16 + React 19, preserving all business logic while replacing the rendering and tooling layers.
Why rewrite rather than upgrade in place: - Babel 6 → Babel 7 requires full preset migration alongside Webpack 4 → 5 (two simultaneous breaking changes) - react-router@3 and react-router-dom@4 are incompatible packages — there is no in-place migration path; v4 was a complete API rewrite - react@17 + react-dom@16.5 mismatch requires a version bump that surfaces React 17/18/19 API changes simultaneously - Node 10 → 24 across 7 major versions while simultaneously upgrading the above is an unacceptable blast radius - A Next.js 16 rewrite starts on a clean baseline and avoids all of the above compounding risks
Target stack for reverb-react modernization:
| Layer | Current | Target |
|---|---|---|
| Framework | CRA-style Webpack 4 bundle | Next.js 16.2.6 (App Router) |
| React | 17.0.1 + react-dom 16.5.0 ⛔ | React 19.2.6 |
| Routing | react-router@3.2.1 + react-router-dom@4.2.2 ⛔ | Next.js App Router file routing |
| Language | JavaScript/JSX | TypeScript 6.0.3 |
| State | Redux 3.7.2 + Flux (mixed) | React Context + Zustand |
| Bundler | Webpack 4.7.0 | Turbopack (Next.js 16 default) |
| Build config | .babelrc Babel 6 |
SWC (built into Next.js) |
| Node | ~10.15.3 ⛔ | 24 LTS |
| UI library | PrimeReact 1.5.1 | PrimeReact 10.9.8 |
| CI | Travis CI (build only) | GitHub Actions |
Modernization path (rewrite, not upgrade):
1. Stand up new apps/legacy-portal/ Next.js 16 scaffold inside the monorepo
2. Port admin/client route structure as Next.js App Router route groups
3. Migrate Redux reducers → Zustand stores (business logic preserved, state shape preserved)
4. Migrate API calls from src/utils/services/ → typed service layer using @soreto/api-client
5. Port components from src/components/ → PrimeReact 10 equivalents (API incompatible — must rewrite)
6. Replace @@PLACEHOLDER@@ config tokens → standard process.env.NEXT_PUBLIC_*
7. Node: goes to 24 from day 1 on the new scaffold (no incremental upgrade needed)
Node security risk during modernization: While the rewrite is in progress, deploy a WAF (Cloudflare or AWS WAF) in front of the current reverb-react Heroku app to compensate for Node 10 EOL exposure.
Effort estimate: 6–10 weeks for one frontend engineer. Rewrite is scoped to the rendering and tooling layers — backend API contracts and business logic do not change.
reverb-backend: Node 14 → 20 → 22 → 24
Blockers to address before each upgrade:
| Blocker | Affects | Action |
|---|---|---|
node-sass@8.0.0 |
All versions | Replace with sass before Node 16+ |
connect-redis@3.4.0 |
Node 18+ | Upgrade to connect-redis@6+ (API breaking change) |
seneca@3.23.3 |
Unknown | Test against newer Node — may work; if not, must replace |
passport@0.3.2 |
Unknown | Upgrade to passport@0.7.x |
superagent@1.8.2 |
Unknown | Replace with axios or upgrade |
universal-analytics |
All | Remove immediately — API is dead |
Recommended path:
1. Remove universal-analytics (no migration — the service is dead)
2. Replace node-sass with sass
3. Test full suite on Node 16 (non-breaking test run)
4. Upgrade connect-redis to v6
5. Upgrade to Node 18 LTS
6. Run CI — fix any failures
7. Upgrade to Node 20, then 22, then 24
soreto-zoe: Node 16 → 18 → 20 → 22 → 24
Blockers to address before each upgrade:
| Blocker | Severity | Action |
|---|---|---|
knex@0.16.3 |
🔴 HIGH | Upgrade to 0.95.x incrementally before any Node upgrade |
puppeteer@9.0.0 |
🟡 MEDIUM | Upgrade to Puppeteer 25.x (PDF generation) — significant API breaking changes across 16 major versions |
bull@3.13.0 |
🟡 MEDIUM | Consider migrating to bullmq (modern fork, active maintenance) |
| TypeScript AMD pattern | 🟡 MEDIUM | Refactor to ES modules before Node 22 upgrade |
Recommended path:
1. Upgrade knex@0.16.3 → 0.95.7 (match reverb-backend, then plan joint upgrade)
2. Upgrade puppeteer@9 → 25.x (significant API changes across 16 major versions — test each processor individually)
3. Upgrade Node 16 → 18
4. Run full build + processor validation
5. Refactor TypeScript to ES modules (AMD removal)
6. Upgrade to Node 20, then 22, then 24
Upgrade Risk by Repo
reverb-react ██████████ HIGHEST (Babel 6, React mismatch — rewrite to Next.js 16, not in-place upgrade)
soreto-zoe ████████░░ HIGH (Knex gap, puppeteer, AMD TypeScript)
reverb-backend ██████░░░░ MEDIUM (seneca unknown risk, connect-redis breaking)
soreto-melissa ██░░░░░░░░ LOW (on Node 22 Maintenance LTS — upgrade to 24)
Key Dependency Blockers
knex@0.16.3 (soreto-zoe)
Knex 0.16 to 0.95 spans 79 minor/patch versions and 3+ years of development. The upgrade must be done incrementally. Key breaking changes along the way:
| Version | Breaking Change |
|---|---|
| 0.17 | Raw query builder changes |
| 0.19 | returning() behavior on PostgreSQL |
| 0.20 | Connection pool interface changes |
| 0.21 | Column type inference changes |
| 0.95 | Async migrations, destroy() changes |
Strategy: Upgrade to the next major milestone, run zoe's build and any available validation, then advance. Document any migrations that need adjustments.
node-sass (reverb-backend, reverb-react)
node-sass is deprecated. It is a C++ binding to LibSass, which is also unmaintained. The replacement is the pure-JS sass package (Dart Sass). Migration:
npm uninstall node-sass
npm install sass
No code changes required in most cases — the API is backwards compatible. Webpack/Next.js configuration may need updating (sass-loader configuration).
seneca@3.23.3 (reverb-backend)
Seneca.js was once a popular Node.js microservice framework. Its GitHub activity has been minimal for several years. The AMQP transport (seneca-amqp-transport) is used for internal process communication in reverb-backend.
Risk assessment: If seneca works on Node 14 and the test suite passes, it may continue to work on Node 18/20. However, there is no guarantee of compatibility with future Node versions, and security vulnerabilities will not be patched.
Options:
1. Keep seneca and test at each Node version — lowest short-term risk
2. Replace with direct RabbitMQ client (amqplib) — medium effort, eliminates dependency
3. Replace with BullMQ (Redis-based) — eliminates RabbitMQ dependency, aligns with zoe's architecture
4. Evaluate whether the internal services (service_meta, service_api) actually need async messaging or could be simplified to direct function calls
puppeteer@9.0.0 (soreto-zoe)
Puppeteer 9 uses Chrome 90. Current Puppeteer 25.x bundles Chrome 136+. The API has significant changes:
- page.goto() options changed
- ElementHandle methods changed
- Browser executable path resolution changed
Since puppeteer is used for PDF generation in affiliate processors, each processor must be tested after upgrade.
Frontend Version Fragmentation
| Package | reverb-react (installed) | Latest available | soreto-melissa (installed) | Notes |
|---|---|---|---|---|
| React | 17.0.1 | 19.2.6 | 18.2.0 | Cannot share components |
| react-dom | 16.5.0 ⛔ | 19.2.6 | 18.2.0 | Mismatch in reverb-react (react≠react-dom) |
| react-router | 3.2.1 + dom 4.2.2 ⛔ | 7.15.1 | N/A | Double mismatch: react-router@3 with react-router-dom@4 |
| Next.js | None | 16.2.6 | 13.4.9 ⚠️ | Melissa only; 3 majors behind |
| PrimeReact | 1.5.1 | 10.9.8 | 10.2.1 | 9 major versions — completely incompatible APIs |
| Webpack | 4.7.0 | 5.106.2 | N/A (SWC) | Divergent; v4→5 is a config rewrite |
| Babel | 6 ⛔ | 7.x | 7 | Babel 6 EOL since 2018 |
| axios | 0.18.0 | 1.16.1 | N/A | Pre-v1 axios in reverb-react |
| redux | 3.7.2 | 5.0.1 | N/A | Two major versions behind |
| react-redux | 5.0.7 | 9.3.0 | N/A | Four major versions behind |
The two frontends cannot share components. The combination of React version mismatch, Babel 6 EOL, two separate react-router mismatches, and Webpack 4 means any component migration must be rewritten for melissa directly.
Backend Version Fragmentation
| Package | reverb-backend | soreto-zoe | Notes |
|---|---|---|---|
| Express | 4.17.1 | 4.16.4 | Minor difference — acceptable |
| Knex | 0.95.7 | 0.16.3 ⚠️ | 3-year gap — critical |
| Winston | 3.1.0 | 3.2.1 | Minor — acceptable |
| Axios | 0.27.2 | ^1.3.4 | Different major — API changes |
| Elasticsearch | 7.13.0 | 7.13.0 | Matched ✓ |
Convergence Strategy
Short-term (0–3 months)
- [ ] Upgrade soreto-zoe's
knex@0.16.3→0.95.7(match reverb-backend) - [ ] Replace
node-sasswithsassin reverb-backend - [ ] Upgrade reverb-backend → Node 18
- [ ] Add
.nvmrcto all repos - [ ] Deploy WAF in front of reverb-react Heroku app (compensating control for Node 10 EOL during modernization)
- [ ] Stand up Next.js 16 scaffold for reverb-react modernization in
apps/legacy-portal/
Medium-term (3–9 months)
- [ ] Upgrade soreto-zoe → Node 18 (after Knex upgrade)
- [ ] Upgrade
puppeteer@9→25.xin soreto-zoe (test each processor) - [ ] Upgrade reverb-backend → Node 20, then 22, then 24
- [ ] Upgrade Express 4.x → 5.x in reverb-backend (now default on npm)
- [ ] Make a decision on
seneca.js(keep or replace) - [ ] Port reverb-react admin + client routes to Next.js 16 App Router (in
apps/legacy-portal/) - [ ] Migrate Redux 3 + Flux → Zustand (business logic preserved)
- [ ] Replace PrimeReact 1.5.1 → 10.9.8 components in modernized portal
Long-term (9–18 months)
- [ ] Upgrade soreto-zoe → Node 24
- [ ] All repos on Node 24 LTS (reverb-react modernized version starts on Node 24)
- [ ] Single shared
.nvmrcat monorepo root - [ ] Unified npm workspace with
packageManagerfield - [ ] Decommission original reverb-react Heroku app once modernized
apps/legacy-portal/is live