Skip to content

feat: trim dependencies, drop Node 16, and target ES2020 - #667

Merged
oliverlaz merged 2 commits into
mainfrom
feat/dependency-cleanup
Sep 1, 2026
Merged

feat: trim dependencies, drop Node 16, and target ES2020#667
oliverlaz merged 2 commits into
mainfrom
feat/dependency-cleanup

Conversation

@oliverlaz

Copy link
Copy Markdown
Member

Removes 19 unused or redundant packages, drops Node 16, and retargets the build from IE 10 to an ES2020 baseline.

Before After
dependencies 9 6
devDependencies 50 34
yarn.lock entries 1266 850 (−33%)
dist min+gzip 42,771 B 38,831 B (−9%)

Removed

  • puppeteer, puppeteer-core — these only supplied a Chrome binary that the CI runner already provides. karma-chrome-launcher resolves google-chrome from PATH, and the puppeteer-installed binary was never wired up via CHROME_BIN, so the Install Chrome step was a no-op. The PUPPETEER_SKIP_DOWNLOAD env in size.yml and the skip-puppeteer action input go with them.
  • request (deprecated since 2020) — replaced with axios, which is already a dependency, across 7 test call sites. The callback-style tests became zero-arg async functions, which also means they now get wrapFn's failure-tracking and skip handling.
  • qs, @types/qs — replaced with native URLSearchParams at the single call site, src/redirect_url.ts. @types/qs had zero references in the published .d.ts.
  • @babel/runtime, @babel/plugin-transform-runtime — helpers are inlined instead. This is the only removal that touches runtime dependencies: consumers stop installing 1.1 MB / 245 files, and the gzipped bundle is actually 75 bytes smaller.
  • @babel/plugin-proposal-class-properties, @babel/plugin-proposal-object-rest-spread, @babel/plugin-transform-object-assign — redundant under preset-env.
  • @babel/node, json-loader, nyc, karma-sauce-launcher — unreferenced anywhere in the repo.
  • husky, @commitlint/cli, @commitlint/config-conventional — dead configuration. The husky.hooks block was v4 syntax that v8 ignores, there was no .husky/ directory, no husky install in prepare, and no commitlint config or workflow invoking either. The pre-commit hook had not been running; CI still enforces lint via lint.yml.
  • eslint-plugin-sonarjs, and @babel/register (unneeded once Node 16 is gone).

Node 16 dropped

Node 16 reached end of life on 2023-09-11. babel-register.js (a bespoke @babel/register shim with a custom import.meta plugin) and the unit-node16 CI job are gone, engines.node moves to >=18, and the README is updated. test-unit-node is now the only unit-test entry point, so CI runs exactly what you run locally — previously the Babel path could drift from the tsx path silently.

ES2020 target

Worth knowing: removing ie >= 10 on its own changes nothing, because last 2 versions still pulls in op_mini all, bb 7, ie_mob and kaios 2.5, which force full ES5 by themselves. A real floor was needed. last 2 versions, not dead was measured too, but it covers only 65.9% of users — it means the two newest releases of each browser. The ES2020 minimums land at 91.3% coverage for ~5 KB more than that aggressive option.

Verification

yarn install --immutable, lint, build, types, test-types and dist all pass. Unit tests: 145 passing. The one local failure is should follow redirect urls, which makes a real HTTP call and 401s without valid credentials — it fails identically before and after this change.

The qsURLSearchParams swap changes a URL that the analytics endpoint parses, so it was done with a characterization test written first: should encode the query string exactly passes unchanged against both the old and new implementations. It pins spaces as %20 (never +) and ~ as literal (never %7E) — the two places where URLSearchParams and qs.stringify diverge, which is what the two .replace() calls in redirect_url.ts are for. Please don't remove them.

The @babel/plugin-proposal-* removals were verified by compiling all 17 src files with and without them and diffing: byte-identical. All 17 files in the built lib/ parse as ES2020 with no ES2021+ syntax.

Two things can only be checked in CI: the cloud integration tests exercising the axios rewrites, and test-browser.

Please look at these

  1. .yarnrc.yml flips enableHardenedMode: truefalse. This is the one line here that is security-relevant rather than cleanup — hardened mode is what makes Yarn verify lockfile integrity against the registry in CI. Included deliberately; happy to split it out.
  2. Semver. Tagged feat: for a minor release as intended, but note that dropping Node 16 and moving the browser floor to Chrome 80 / Safari 13.1 are breaking for anyone on those runtimes. Release notes should call out all three consumer-visible changes: the Node floor, the browser floor, and @babel/runtime no longer being installed.
  3. A test was passing for the wrong reason. files.js fetched http://nodejs.org/images/logo.png, which now returns 404. It passed anyway because form-data derived the filename from request's internals rather than the response, so it was uploading an HTML error page and asserting on the name. Now points at a live URL with an explicit filename.

Also fixed

karma.config.js replaced the base webpack plugins instead of extending them, dropping the DefinePlugin that defines process.env.PACKAGE_VERSION. Combined with EnvironmentPlugin only substituting env keys that are actually set, this left bare process.env references in the bundle and produced process is not defined whenever credentials were absent. It now extends the base plugins and supplies defaults for the five variables the bundle reads, so a credential-less run fails with the tests' own error message instead.

Removes 19 unused or redundant packages, drops Node 16 support, and retargets the build from IE 10 to an ES2020 baseline. Dependencies go from 9 to 6, devDependencies from 50 to 34, and the lockfile from 1266 to 850 entries.

Removed:

- puppeteer, puppeteer-core — only supplied a Chrome binary the CI runner already provides. karma-chrome-launcher resolves google-chrome from PATH, and the puppeteer-installed binary was never wired up via CHROME_BIN, so the install step was a no-op.
- request — replaced with axios (already a dependency) across 7 test call sites. The stream-upload test was also pointed at a live URL; its previous one had started returning 404, so the test was uploading an error page and asserting on the filename.
- qs, @types/qs — replaced with native URLSearchParams at the single call site in src/redirect_url.ts. The encoding is byte-identical and is now pinned by a test, since the analytics endpoint parses that URL.
- @babel/runtime, @babel/plugin-transform-runtime — helpers are inlined instead. Gzipped output is unchanged and consumers no longer install 1.1 MB of runtime helpers.
- @babel/plugin-proposal-class-properties, @babel/plugin-proposal-object-rest-spread, @babel/plugin-transform-object-assign — redundant under preset-env; verified by a byte-identical build.
- @babel/node, json-loader, nyc, karma-sauce-launcher — unreferenced anywhere in the repo.
- husky, @commitlint/cli, @commitlint/config-conventional — dead configuration. The husky.hooks block was v4 syntax that v8 ignores, there was no .husky directory or commitlint config, and no workflow invoked either, so the pre-commit hook had not been running.
- eslint-plugin-sonarjs.
- @babel/register — no longer needed once Node 16 is dropped.

Node 16 reached end of life on 2023-09-11 and is no longer supported: babel-register.js and the unit-node16 CI job are removed and engines.node moves to >=18.

The Babel target moves from "ie >= 10" to an ES2020 baseline. Note that removing "ie >= 10" alone changed nothing, because "last 2 versions" still pulled in op_mini, BlackBerry and kaios, which force ES5 on their own. The new floor cuts the gzipped browser bundle from 42,771 to 38,831 bytes (-9%) at 91% global browser coverage.

Also fixes karma.config.js replacing the base webpack plugins rather than extending them, which left process.env references unsubstituted whenever credentials were absent and produced a "process is not defined" error in the browser suite.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Size Change: +17.5 kB (+16.01%) ⚠️

Total Size: 127 kB

📦 View Changed
Filename Size Change
dist/js_min/getstream.js 38.8 kB +3.29 kB (+9.26%) 🔍
dist/js/getstream.js 88.2 kB +14.2 kB (+19.26%) ⚠️

compressed-size-action

testdouble 3.20.2 added lib/can-register-loader.js, which does `require('module')`. webpack 5 does not polyfill Node builtins for browser targets, so the karma bundle failed to compile and emitted no asset for the browser-test-helper entry. karma-webpack then readFileSync'd that missing asset (lib/webpack/plugin.js:22), threw ENOENT, and never exited — turning a six-second build error into an indefinite hang.

Stubbing `module` resolves it to an empty object, so testdouble's `Module.register` check is undefined, which is the correct answer in a browser.

Also caps the browser job at 10 minutes, since karma-webpack reports bundle failures as hangs rather than errors. A healthy run takes about two minutes.
@oliverlaz
oliverlaz merged commit f385a45 into main Sep 1, 2026
13 checks passed
@oliverlaz
oliverlaz deleted the feat/dependency-cleanup branch September 1, 2026 12:41
@github-actions github-actions Bot mentioned this pull request Sep 1, 2026
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.

2 participants