audit: append Context7-assisted dependency upgrade analysis (§34)
Companion to the deps-auditor report. Per-major pros/cons informed by upstream changelogs queried via Context7. Sequencing: - Tier A (patches + esbuild minor) → do now - Zod 4 + @hookform/resolvers 5 → couple together, codemod-able - Next 15 → 16 (incl. middleware → proxy.ts rename) → 2-4 weeks - Tailwind 4 → afternoon project, visual review pages - Defer indefinitely: archiver 8 (failed last try), react-day-picker 10 Top-line baseline: 0 known vulns; no GPL/AGPL; lockfile reproducible. Everything below is dev-experience/perf, not security-blocker. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6506,3 +6506,201 @@ No CDN / `s-maxage` fronts hot reads. Per-page avatar GET burns a presign + S3 r
|
||||
4. **H1 + H2** port-binding plumbing (small refactor, big invariant).
|
||||
5. **H3 + H4 + M2** streaming pass over backup + migrator + email attachments.
|
||||
6. Remainder during next storage-config UI sweep.
|
||||
|
||||
---
|
||||
|
||||
## 34. Dependency upgrade analysis — Context7-assisted (follow-up after deps-auditor)
|
||||
|
||||
_Post-session follow-up. Where the original `deps-auditor` covered abandonment + vulnerabilities, this section queries upstream changelogs via Context7 to weigh the pros/cons of pulling every available major. Use this as your bump roadmap._
|
||||
|
||||
# Dependency upgrade analysis (Context7-assisted)
|
||||
|
||||
Companion to the deps-auditor report from the original 33-agent run.
|
||||
That auditor checked vulnerabilities + abandonment + license risk; this
|
||||
follow-up adds **per-dep pros/cons of bumping to the latest stable**,
|
||||
informed by upstream changelogs/docs queried via Context7.
|
||||
|
||||
**Top-line baseline:** `pnpm audit` reports **0 known vulnerabilities**.
|
||||
No GPL/AGPL contamination. Lockfile reproducible. We are safe TODAY
|
||||
without any upgrade; everything below is "should we pull the next
|
||||
major in?" prioritization.
|
||||
|
||||
---
|
||||
|
||||
## At a glance — what's outdated
|
||||
|
||||
| Package | Current | Latest | Bump size |
|
||||
|---|---|---|---|
|
||||
| `next` | 15.5.18 | 16.2.6 | major |
|
||||
| `eslint-config-next` | 15.5.18 | 16.2.6 | major (matches next) |
|
||||
| `zod` | 3.25.76 | 4.4.3 | major |
|
||||
| `tailwindcss` | 3.4.19 | 4.3.0 | major |
|
||||
| `@hookform/resolvers` | 3.10.0 | 5.2.2 | TWO majors |
|
||||
| `archiver` | 7.0.1 | 8.0.0 | major |
|
||||
| `react-day-picker` | 9.14.0 | 10.0.0 | major |
|
||||
| `eslint` | 9.39.4 | 10.3.0 | major |
|
||||
| `esbuild` | 0.27.7 | 0.28.0 | pre-1.0 minor (effectively major) |
|
||||
| `@playwright/test` | 1.59.1 | 1.60.0 | minor |
|
||||
| `libphonenumber-js` | 1.12.43 | 1.13.1 | minor |
|
||||
| `tailwind-merge` | 3.5.0 | 3.6.0 | minor |
|
||||
| `bullmq` | 5.76.6 | 5.76.8 | patch |
|
||||
| `@tanstack/react-query` | 5.100.9 | 5.100.10 | patch |
|
||||
| `better-auth` | 1.6.9 | 1.6.10 | patch |
|
||||
| `vitest` | 4.1.5 | 4.1.6 | patch |
|
||||
| `lint-staged` | 17.0.3 | 17.0.4 | patch |
|
||||
| `@vitest/coverage-v8` | 4.1.5 | 4.1.6 | patch |
|
||||
|
||||
`@types/node` deliberately pinned to ^20.19 to match Node 20 runtime
|
||||
(audit findings — was previously ^25 against a Node 20 runtime, which
|
||||
greenlit non-existent APIs).
|
||||
|
||||
---
|
||||
|
||||
## Tier A — Pull the patches in now (zero-risk wins)
|
||||
|
||||
`bullmq`, `@tanstack/react-query` + `react-query-devtools`,
|
||||
`better-auth`, `vitest` + `@vitest/coverage-v8`, `lint-staged`,
|
||||
`@playwright/test`, `libphonenumber-js`, `tailwind-merge`.
|
||||
|
||||
**Pros:** patch / minor bumps, bug fixes only, no API changes documented.
|
||||
**Cons:** none material — pin-bumps after a 30-second `pnpm install`
|
||||
verify and full vitest run.
|
||||
**Recommended:** **DO** as one batch commit. ~5 minutes.
|
||||
|
||||
---
|
||||
|
||||
## Tier B — Per-major analysis
|
||||
|
||||
### B-1 — Next.js 15.5 → 16.2 *(touches every API route + middleware)*
|
||||
|
||||
**Upstream summary (via Context7):**
|
||||
|
||||
- **`middleware.ts` is renamed to `proxy.ts`** in Next 16. The named export `middleware` → `proxy`. Config flags rename (`skipMiddlewareUrlNormalize` → `skipProxyUrlNormalize`). **Edge runtime is NOT supported in `proxy`** — if you need edge runtime you must keep `middleware.ts` (we already use the Node runtime, so this is just a rename for us).
|
||||
- Async `cookies()` / `headers()` / `params` / `searchParams` was the Next-15 change; Next 16 hardens the warning into an error. We're already async-safe (CLAUDE.md confirms the upgrade landed).
|
||||
- Automated codemod: `npx @next/codemod@canary upgrade latest` handles the rename + most boilerplate.
|
||||
|
||||
**Risk for us:**
|
||||
- `src/middleware.ts` rename is a 30-second edit; no semantic change for us because we don't depend on edge runtime.
|
||||
- The Documenso webhook + websocket server custom-server path (`src/server.ts`) needs to be retested — Next 16 changed some internals around the custom-server contract.
|
||||
- `eslint-config-next` must bump in lockstep (already at 15.5.18 → 16.2.6).
|
||||
- Turbopack defaults shifted; our dev script (`next dev --turbopack -H 0.0.0.0`) needs a quick smoke run.
|
||||
|
||||
**Recommended:** **WAIT 2-4 weeks.** Next 16 dropped recently; let the field's bug reports settle. Then run the codemod + a full playwright smoke. Effort: 1-2h.
|
||||
|
||||
---
|
||||
|
||||
### B-2 — Zod 3 → 4 *(touches every validator file)*
|
||||
|
||||
**Upstream summary (via Context7):**
|
||||
|
||||
- Top-level format helpers — `z.email()` / `z.uuid()` / `z.url()` etc. replace `z.string().email()` / `.uuid()` / `.url()`. Old form is **deprecated** but still works.
|
||||
- Error customization unified: `{ message: '...' }` → `{ error: '...' }`. Old form deprecated.
|
||||
- `z.function()` API completely redesigned — now takes `input`/`output` schemas upfront, returns a function factory (not a schema).
|
||||
- ~14× perf improvement on parse paths.
|
||||
- TypeScript server perf improvement (generic-class-signature simplification).
|
||||
|
||||
**Risk for us:**
|
||||
- We have ~30 validator files using `z.string().email()` / `.uuid()` style and `{ message: '...' }` style throughout. Both still work in 4.x but produce deprecation warnings on every parse — noisy in logs.
|
||||
- `@hookform/resolvers` v5 supports **both** Zod 3 and Zod 4 natively (auto-detects), so this couples cleanly with B-4 below.
|
||||
- We don't use `z.function()` anywhere, so the biggest breaking change is a non-issue for us.
|
||||
|
||||
**Recommended:** **GO once Tier A is in.** Codemod-friendly: a single Find/Replace pass on `z.string().email()` → `z.email()` etc. covers ~95% of the churn. Effort: 2-3h including running full vitest + writing replacement codemods.
|
||||
|
||||
---
|
||||
|
||||
### B-3 — Tailwind CSS 3 → 4 *(touches `tailwind.config.ts`, `globals.css`, every dynamic-class site)*
|
||||
|
||||
**Upstream summary (via Context7):**
|
||||
|
||||
- **All-new Oxide engine** — 5× faster full builds, 100× faster incremental.
|
||||
- **CSS-first config:** `tailwind.config.ts` is gone. Theme defined in `globals.css` via `@theme` + CSS custom properties (`--color-brand: …`).
|
||||
- **PostCSS plugin consolidation:** `postcss.config.mjs` switches from `tailwindcss + autoprefixer + postcss-import` plugins to single `@tailwindcss/postcss`.
|
||||
- Built on native cascade layers, OKLCH colors, container queries, `@starting-style`, popovers.
|
||||
- Official automated upgrade tool: `npx @tailwindcss/upgrade` (requires Node 20+, which we already use).
|
||||
|
||||
**Risk for us:**
|
||||
- We have a custom `tailwind.config.ts` with brand tokens, CVA + tailwind-merge + clsx, plus the `tailwindcss-animate` plugin. The upgrade tool migrates most of this automatically; the manual review is the design-token spread across `globals.css`.
|
||||
- shadcn/ui components (`components/ui/*`) use `cn()` + arbitrary values heavily. Some `[--variable]` syntax has changed in v4.
|
||||
- `tailwindcss-animate` may not yet support v4 — need to confirm or swap for `tailwindcss-animated` (the v4 successor).
|
||||
|
||||
**Recommended:** **HIGH-RISK / HIGH-REWARD.** Park until you have a clear afternoon. The build-time speedup is genuinely meaningful for dev experience. Run the official upgrade tool on a throwaway branch first; visually diff a handful of critical pages before merging. Effort: 3-4h on a focused day; visual regressions are the variable.
|
||||
|
||||
---
|
||||
|
||||
### B-4 — `@hookform/resolvers` 3 → 5 *(touches every form file)*
|
||||
|
||||
**Upstream summary (via Context7):**
|
||||
|
||||
- v5 supports **both Zod 3 and Zod 4** simultaneously via auto-detection — pulls `zod/v4` if you opt into it explicitly.
|
||||
- Resolver options shape is the same as v3 (`{ mode: 'async' | 'sync', raw?: boolean }`).
|
||||
- v4 was a transitional version with the same external API; v5 is the stable cut.
|
||||
|
||||
**Risk for us:**
|
||||
- Coupled with the Zod 4 upgrade — if we stay on Zod 3, v5 still works (the resolver detects Zod-3 schemas via shape probing). Bumping resolvers without bumping Zod is safe.
|
||||
|
||||
**Recommended:** **GO IN LOCKSTEP with B-2 (Zod 4).** Effort: 5 min once Zod 4 is in.
|
||||
|
||||
---
|
||||
|
||||
### B-5 — `archiver` 7 → 8 *(touches GDPR-export bundle + backup-restore)*
|
||||
|
||||
**Upstream summary:** Library "/gajus/archiver" not found in Context7 — fallback to npm changelog. We previously rolled back archiver@8 to archiver@7 (in commit `04a5949` per CLAUDE.md history) because of dropped default-export changes that broke our TS types. v8 stabilised since then.
|
||||
|
||||
**Risk for us:**
|
||||
- Last time we tried this it broke. Read the v8 changelog before retrying.
|
||||
- Used only for GDPR export + backup-restore — narrow blast radius. A failed upgrade is non-customer-facing.
|
||||
|
||||
**Recommended:** **DEFER.** Stay on 7 until either v8 demonstrably fixes a CVE / bug we care about, or until we have a green test suite to verify nothing regressed. Re-attempt only when there's a forcing function.
|
||||
|
||||
---
|
||||
|
||||
### B-6 — `react-day-picker` 9 → 10 *(touches every date-picker site)*
|
||||
|
||||
**Upstream summary:** v10 is a recent cut. Without Context7 returning a hit on its changelog, treat as "investigate before pulling".
|
||||
|
||||
**Risk for us:**
|
||||
- Used in ~6 surfaces (reminder form, EOI date fields, expense date, invoice due-date, dashboard date-range picker). A breaking change to the calendar render path would affect every form.
|
||||
|
||||
**Recommended:** **DEFER 2-3 weeks** to let bug reports surface. Effort to actually do it: ~1h once the spec is reviewed.
|
||||
|
||||
---
|
||||
|
||||
### B-7 — `eslint` 9 → 10 + `eslint-config-next` *(touches CI)*
|
||||
|
||||
**Risk for us:**
|
||||
- ESLint 10 likely drops support for some legacy rule configs.
|
||||
- `eslint-config-next` should bump in lockstep with `next` (B-1).
|
||||
|
||||
**Recommended:** **PAIR WITH B-1.** No standalone value to bumping eslint without bumping Next.
|
||||
|
||||
---
|
||||
|
||||
### B-8 — `esbuild` 0.27 → 0.28 *(touches build pipeline)*
|
||||
|
||||
**Risk for us:**
|
||||
- We use esbuild via `pnpm.overrides` plus directly in `build:server` and `build:worker` scripts.
|
||||
- Pre-1.0 minors at esbuild are typically very safe (Evan Wallace ships tight changelogs), but they do occasionally drop deprecated flags.
|
||||
|
||||
**Recommended:** **GO.** Bundle the bump with the Tier A patches. Effort: 1 min + a `pnpm build` smoke.
|
||||
|
||||
---
|
||||
|
||||
## Tier C — Things to leave alone
|
||||
|
||||
- **`drizzle-orm 0.45.2`** — current major. No upgrade needed.
|
||||
- **`react 19.2.6` / `react-dom 19.2.6`** — current React 19. Stable.
|
||||
- **`@radix-ui/*`** — all current. These ship patch updates frequently; consider a quarterly sweep but not blocking.
|
||||
- **`@dnd-kit/*`, `@pdfme/*`, `socket.io`, `bullmq`, `pino`, `postgres`, `minio`, `ioredis`, `pdf-lib`, `pdfkit`, `sharp`, `tesseract.js`, `recharts`, `cmdk`, `vaul`, `sonner`, `zustand`, `next-themes`, `date-fns`, `clsx`, `class-variance-authority`, `jose`, `nodemailer`, `mailparser`, `imapflow`, `openai`, `lucide-react`, `react-easy-crop`, `react-hook-form`** — all current within their major lines and either no risk-worthy bump available or already bumped.
|
||||
|
||||
---
|
||||
|
||||
## Recommended sequencing
|
||||
|
||||
1. **Now** — pull Tier A patches as one commit (~5 min).
|
||||
2. **Now** — `esbuild` 0.27 → 0.28 in same commit.
|
||||
3. **Next focused half-day** — Zod 4 + `@hookform/resolvers` v5 together. Coupled because resolvers v5 supports both. Codemod-able.
|
||||
4. **2–4 weeks** — Next 15 → 16 + `eslint-config-next` 16 + `eslint` 10. Lockstep. Run `@next/codemod` first.
|
||||
5. **When a tester-friendly afternoon opens up** — Tailwind 4 via the official upgrade tool, with visual review across critical pages.
|
||||
6. **Defer indefinitely** — archiver 8, react-day-picker 10 (neither is delivering us anything we need).
|
||||
|
||||
**Non-goal:** chasing the bleeding edge on every dep. The audit's baseline finding stands — we are secure today. These are mostly developer-experience and perf wins, not security blockers.
|
||||
|
||||
Reference in New Issue
Block a user