Skip to content

chore: drop the qs resolution and nine unused dependencies - #2146

Merged
netomi merged 2 commits into
mainfrom
chore/webui-express-5
Sep 3, 2026
Merged

chore: drop the qs resolution and nine unused dependencies#2146
netomi merged 2 commits into
mainfrom
chore/webui-express-5

Conversation

@netomi

@netomi netomi commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Cleans up webui/package.json: the qs resolution goes away, and nine dependencies nothing imports go with it.

The qs resolution

resolutions.qs: ^6.14.1 existed because express 4 caps qs at ~6.14.0. That ceiling is not something a version range on express can lift — ^4.21.0 already resolves to 4.22.1, and 4.22.1 is the version that declares ~6.14.0.

Express 5.1.0+ declares qs: ^6.14.0, so upgrading it lets the pin go and qs resolves to 6.16.0 on its own — ahead of the 6.15.2 the resolution was forcing.

Express 5 routes through path-to-regexp v8, where a bare '*' is no longer a valid path:

PathError [TypeError]: Missing parameter name at index 1: *

So the standalone frontend server's catch-all becomes app.get('/{*splat}', …). The braces matter — a bare /*splat does not match the root path.

The @types/react resolution stays

@types/react-infinite-scroller@1.2.5 declares its dependency as "@types/react": "*". Yarn resolves each descriptor independently, so * becomes the newest release (19.2.18); it cannot satisfy ^18.2.0, so a second copy of the React types lands nested under that package and tsc fails with TS2786 on InfiniteScroll and TS2742 on an inferred csstype reference.

Two alternatives were tried and neither works:

  • packageExtensions only adds missing dependencies; it does not override a range a package already declares. The nested v19 stayed.
  • yarn dedupe only has a "highest" strategy, so it keeps 19 rather than collapsing onto 18.3.x.

The pin therefore holds until this app moves to React 19. Since JSON carries no comments, the reason sits in a "//resolutions" key that yarn ignores, right above the block.

Unused dependencies

depcheck flagged these; each was confirmed by searching src, test, configs, eslint.config.mjs and the scripts, and by removing them and running the full pipeline.

Package Was in Still installed afterwards?
clsx dependencies yes — MUI pulls 2.1.1; ours pinned ^1.2.1, a stale major
prop-types dependencies yes — @mui/material, @mui/private-theming
punycode dependencies yes — tr46, uri-js
@types/d3-scale devDependencies yes — @mui/x-charts-vendor
@types/d3-shape devDependencies yes — @mui/x-charts-vendor
@types/prop-types devDependencies yes — @mui/utils, @types/react
@types/react-transition-group devDependencies yes — @mui/material, @mui/x-date-pickers
@types/punycode devDependencies no — leaves the install
ts-node devDependencies no — leaves the install

The only prop-types match in the codebase is 'react/prop-types': 'off' in eslint.config.mjs, which is an eslint rule name rather than the package.

depcheck also flagged rimraf, which is a false positive — the clean script uses it. It stays.

Note that clsx, prop-types and punycode were runtime dependencies, so this narrows the published package's dependency contract. Nothing in the library imports them, but a consumer who happened to get them transitively from openvsx-webui no longer will.

Lockfile

251 insertions, 263 deletions, all of it express's own subtree moving from the 4.x generation to 5.x: 4 packages added (router, is-promise, once, wrappy), 6 removed (array-flatten, destroy, methods, mime, safe-buffer, utils-merge), 28 version changes. The two that matter are qs: 6.15.2 -> 6.16.0 and path-to-regexp: 0.1.13 -> 8.4.2. React, MUI, vite and eslint are untouched.

Testing

  • yarn lint — clean
  • yarn build (tsc + lint) — clean
  • yarn test — 260 tests in 50 files, all passing
  • yarn build:default — vite builds the app
  • yarn install --immutable — passes, so CI will accept the lockfile
  • The standalone server run on Express 5 against the built dist: /, /index.html, /extension/foo/bar, /user-settings/profile and /deep/path all return the SPA index, and with -ratelimit -ratelimit-limit 3 the fourth request returns 429, confirming express-rate-limit 7.5.1 still works on Express 5

src/default/server.ts has no unit test: it calls app.listen at import time and has no existing harness, so the route change was verified by running the server as described above.

The qs resolution existed because express 4 caps qs at ~6.14.0. Express 5
declares ^6.14.0 instead, so upgrading it lets the pin go and qs resolves
to 6.16.0 on its own. Express 5 routes through path-to-regexp v8, where a
bare '*' is no longer a valid path, so the standalone server's catch-all
becomes '/{*splat}' - the braces keep it matching the root path.

The @types/react resolution stays: @types/react-infinite-scroller asks for
@types/react as *, which resolves to v19 and puts a second copy of the
React types in the tree, breaking the build. Neither packageExtensions nor
yarn dedupe can express that, so the pin holds until this app moves to
React 19. Recorded that next to it, since JSON cannot carry a comment.

Nothing imports clsx, prop-types, punycode, @types/d3-scale,
@types/d3-shape, @types/prop-types, @types/punycode,
@types/react-transition-group or ts-node, so they go too. Only the last
two of those leave the install - the rest are pulled in by MUI or by the
URL parsers that actually use them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@netomi
netomi requested review from gnugomez and a lite review from Copilot September 3, 2026 12:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

Changes are cohesive dependency hygiene plus a small, validated Express 5 compatibility update, with only a minor changelog grammar nit noted.

Pull request overview

This PR cleans up the webui workspace dependency graph by removing an unneeded qs resolution (enabled by upgrading to Express 5), dropping nine unused direct dependencies, and updating the standalone frontend server’s catch-all route for Express 5 / path-to-regexp v8.

Changes:

  • Upgrade express to ^5.1.0 (and @types/express to ^5.0.0), allowing qs to resolve without a manual resolution pin.
  • Remove unused direct dependencies from webui/package.json (runtime and dev) and update yarn.lock accordingly.
  • Update the standalone server SPA fallback route to app.get('/{*splat}', …) and document the change in CHANGELOG.md.
File summaries
File Description
webui/yarn.lock Updates the lockfile for Express 5 and the dependency removals, including qs resolving to a newer version without a resolution override.
webui/src/default/server.ts Adjusts the SPA catch-all route syntax to be compatible with Express 5 / path-to-regexp v8.
webui/package.json Removes the qs resolution and unused dependencies; keeps the @types/react resolution with an inline explanation key.
webui/CHANGELOG.md Documents the dependency cleanup and Express upgrade for the webui changelog.
Review details
  • Files reviewed: 3/4 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread webui/CHANGELOG.md Outdated
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@netomi

netomi commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

The starting point for that PR was to remove the pinned resolution for qs, while upgrading express some unused deps were detected that are safe to remove.

@netomi
netomi merged commit 1b1c8f2 into main Sep 3, 2026
5 checks passed
@netomi
netomi deleted the chore/webui-express-5 branch September 3, 2026 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants