Date: 2026-04-01 Status: Accepted Deciders: Aditya Kumar Darak
When upgrading major devDependencies (eslint 10, jsdom 29, typescript 6, vite 8)
in PR #42, two transitive-dependency issues blocked npm install:
-
vite-plugin-pwa 1.2.0 declares
peerDependencies.viteas^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0and has not yet added^8.0.0, even though the plugin works correctly with vite 8 in production (vite-pwa/vite-plugin-pwa#918). -
workbox-build 7.4.0 (a dependency of vite-plugin-pwa) pulls in
@rollup/plugin-terser@0.4.4, which depends onserialize-javascript@^6.0.1. That range is vulnerable to CVE-2026-34043 (CPU-exhaustion DoS via crafted array-like objects). The fix requiresserialize-javascript >= 7.0.5. A newer@rollup/plugin-terser@1.0.0already depends onserialize-javascript@^7.0.3, butworkbox-buildhas not updated its constraint yet.
The full vulnerable chain:
vite-plugin-pwa@1.2.0
-> workbox-build@7.4.0
-> @rollup/plugin-terser@0.4.4
-> serialize-javascript@^6.0.1 (CVE-2026-34043)
Add two entries to package.json overrides:
Pros:
- npm's built-in, first-class mechanism for exactly this use case.
- Zero code changes; same runtime behavior.
- Fixes the CVE and the peer-dep conflict immediately.
- Removable the day upstream publishes a fix (one-line deletion each).
- Already used in this project for the same
serialize-javascriptissue.
Cons:
- Overrides must be reviewed when upstream packages release new versions.
- Easy to forget they exist if not documented (this ADR addresses that).
Write ~50 lines of custom code that builds the service worker and injects the precache manifest.
Pros:
- Removes the entire vulnerable transitive chain.
- No overrides needed.
Cons:
- We own the code; nobody else audits it.
- Must be maintained when Vite's plugin API or workbox module structure changes.
- Loses community-maintained edge-case handling.
- Higher long-term maintenance burden for a temporary upstream gap.
Fork the repo, update the peer dep, install from our fork.
Pros:
- Fixes the peer dep issue at the source.
Cons:
- Git-based npm dependencies are fragile (build from source required).
- Must track upstream and rebase our fork.
- More moving parts than an override for the same result.
Keep vite at v7 in this PR; bump only eslint, jsdom, and typescript.
Pros:
- No workarounds needed for the peer dep issue.
Cons:
- Does not fix the serialize-javascript CVE (still in the tree via vite-plugin-pwa).
- Delays adoption of vite 8.
Option A: npm overrides.
The overrides are temporary bridges while upstream catches up. They require zero code changes, fix the security vulnerability, and carry the lowest maintenance burden. This ADR and the linked tracking issues ensure they are not forgotten.
| Override | Remove when | Upstream issue |
|---|---|---|
serialize-javascript: "^7.0.5" |
workbox-build updates @rollup/plugin-terser to ^1.0.0 (which depends on serialize-javascript@^7.0.3) |
Tracked in our repo |
vite-plugin-pwa: { vite: "$vite" } |
vite-plugin-pwa adds ^8.0.0 to its vite peer dep |
vite-pwa/vite-plugin-pwa#918 |
How we will know: Dependabot creates PRs when these packages publish new versions. Each Dependabot PR is an opportunity to check whether the override is still needed and remove it if not.
npm auditwill report zero vulnerabilities after this change.- Dependabot PRs for
vite-plugin-pwaandworkbox-buildshould be reviewed with an eye toward removing overrides. - If either override is removed, update this ADR's status to reflect which overrides remain (or mark it as superseded when both are gone).