Skip to content

Upgrade dev dependencies - #91

Open
troberts-28 wants to merge 11 commits into
developfrom
chore/dev-dep-upgrades
Open

troberts-28 wants to merge 11 commits into
developfrom
chore/dev-dep-upgrades

Conversation

@troberts-28

@troberts-28 troberts-28 commented Sep 1, 2026 •

Copy link
Copy Markdown
Owner

What

  • Removes two deprecated packages and upgrades the rest of the dev toolchain: Jest 30, Prettier 3, builder-bob 0.43, perfectionist 5, react-hooks 7, lint-staged 17, TypeScript 5.9.
  • Stops publishing 84 compiled test files, and ships src so builder-bob's declaration maps resolve.
  • Leaves the react / react-native / RNTL group alone, since moving it means raising the published peerDependencies floor.

Why

  • @types/react-native is a stub npm itself deprecates (react-native ships its own types), and @eslint/compat became unused once react-hooks 7 removed the need for its flat-config shim.
  • Prettier 3 also clears a live unmet peer: eslint-plugin-prettier already required >=3.0.0 against the pinned 2.8.8.

Review Notes

  • builder-bob 0.43 and the packaging change both alter published output, so dist/ was diffed rather than trusted to a green build. JSX moves to the automatic runtime (verified react/jsx-runtime resolves on react 18.2.0, the peer floor), and the tarball is 122 kB against 168.9 kB for 2.7.0 despite now including src.
  • Three upgrades are deliberately absent, each blocked upstream: eslint 10 (eslint-plugin-react caps at ^9.7), TypeScript 7 (typescript-eslint declares <6.1.0), and Babel 8 (breaks all 14 test suites — RN 0.72's jest/setup.js mis-transforms under it via the deprecated metro babel preset).

troberts-28 and others added 11 commits August 31, 2026 23:19
`yarn set version` writes explicit opt-outs for the supply-chain gates
added between 4.13 and 4.18, so the upgrade preserves old behaviour rather
than adopting the new defaults. Two of those three are dropped here:

- approvedGitRepositories: "**" — removed. The lockfile has no git
  dependencies, so this only pre-approves ones nobody has vetted yet.
- npmMinimalAgeGate: 0 — removed, taking the 1-day default. Newly published
  versions are quarantined before they can be installed. Verified a clean
  install still resolves with the gate active.
- enableScripts: true — kept. Four packages need build scripts, and
  simple-git-hooks installs the pre-commit hook from `prepare`.

Lockfile churn is 5 lines; no dependency resolutions change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
@types/react-native is a stub package — npm's own deprecation says react-native
provides its own type definitions, which it has since 0.71. Nothing referenced it
and `yarn ts` is unchanged without it.

@babel/core 7.29.7, eslint-plugin-prettier 5.5.6, lint-staged 16.4.0,
simple-git-hooks 2.14.0, typescript-eslint 8.68.0, typescript 5.9.3. Most specs
were already wide enough and only needed a lockfile refresh.

typescript-eslint takes 8.68.0 rather than 8.69.0: the npmMinimalAgeGate default
adopted alongside yarn 4.18 quarantines 8.69.0, published 15 hours ago. It will
resolve on its own once past the 1-day window.

@types/react stays at >=18.2.0, deliberately wide to track the react peer floor.

Also fixes the lint-staged glob `*.{json}` -> `*.json`, which printed a warning
on every commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
eslint-plugin-perfectionist 4 -> 5.10.1 and eslint-plugin-react-hooks 5 -> 7.1.1.
Both work on eslint 9; eslint 10 itself stays blocked on eslint-plugin-react,
whose latest (7.37.5) still caps at `^9.7`.

perfectionist 5 changes `newlinesBetween` from "always"/"never" to a number, so
sort-imports now passes 1.

react-hooks 7 is flat-config native, so the fixupPluginRules shim is gone —
verified rules-of-hooks still fires by linting a deliberate conditional-hook
violation, not just by a clean run. That leaves @eslint/compat unused, so it is
removed rather than bumped.

No new warnings: `eslint src/ examples/ --max-warnings 0` is clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
jest, babel-jest and @types/jest to 30. The suite needed no migration: there
were no deprecated matcher aliases, no jest.genMockFromModule, no jest.mock()
calls at all and no --testPathPattern in scripts, and TypeScript is already
above Jest 30's 5.4 floor.

The open risk was jest.config.js's `preset: "react-native"`, which resolves out
of the react-native devDep at 0.72.0 — well before Jest 30 existed. It works:
all 380 tests pass across 14 suites.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
This is the one dev dependency that changes what ships to npm, so the output was
diffed rather than trusted to a green check suite. Three changes:

- JSX now compiles through the automatic runtime (react/jsx-runtime) instead of
  React.createElement. Verified react/jsx-runtime resolves on react 18.2.0, the
  peer floor, so no consumer loses out.
- dist/commonjs/package.json is emitted with {"type":"commonjs"}, which is a
  correctness fix for Node ESM interop.
- 43 .d.ts.map declaration maps are new.

Net effect on the tarball is smaller despite 44 more files: 118.3 kB packed and
1.07 MB unpacked, against 168.9 kB / 1.6 MB for the published 2.7.0. main,
module, types and typings all still resolve.

The documented 0.43 breaking changes (vite-config `conditions: ['source']`, the
metro-config drop) do not apply — neither is used here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
Also clears a live unmet peer dependency: eslint-plugin-prettier already
required prettier >=3.0.0, so every install printed a YN0060 warning against
the pinned 2.8.8. That warning is gone.

Churn is one line. .prettierrc sets every option explicitly, including
trailingComma: "es5", so prettier 3's default change to "all" does not apply
here and the reformat is limited to parenthesising a nullish coalescing
expression inside JSX. No .git-blame-ignore-revs needed at this size.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
The spec is `>=18.2.0`, deliberately wide to track the react peer floor, so the
lockfile was already satisfied at 19.1.4 and a plain install would never move it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
dist carried 84 compiled test files to consumers. bob's default exclude only
covers __tests__/__fixtures__/__mocks__, and this repo keeps tests in src/tests,
so they went straight through.

Two changes were needed, because the exclude only governs the babel targets:

- bob `exclude` widened to cover `tests`, which handles commonjs and module.
- the typescript target now builds against tsconfig.build.json via bob's
  `project` option. `yarn ts` still uses tsconfig.json, so tests remain
  typechecked — verified by injecting a type error into a test and watching
  `yarn ts` fail, then pass again once reverted.

bob 0.43 hardcodes --declarationMap, and those maps referenced ../../src, which
`files` did not publish, so they were dead weight. Rather than strip them, src
now ships (minus tests) and they resolve, giving consumers go-to-definition into
real TypeScript.

Net: 175 dist files against 259, no tests published, and 122 kB packed versus
168.9 kB for the published 2.7.0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
Requires node >=22.22.1, which the .nvmrc added alongside the Node 24 CI move
already satisfies. v17 drops Listr2, so hook output is plain status lines rather
than interactive spinners, and node_modules shrinks noticeably.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
Both were pinned one release back because yarn's npmMinimalAgeGate quarantined
them mid-upgrade: 8.69.0 was 15 hours old and 5.11.0 was 23. Well past the
1-day window now, and both install clean.

No new lint output: `eslint src/ examples/ --max-warnings 0` still passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
jest and babel-jest 30.5.1, lint-staged 17.5.1, react-native-builder-bob 0.43.1.

builder-bob is the only one that touches published output, so dist was rebuilt
and compared against 0.43.0: identical file list and byte-identical contents.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JJ2weaFu4jhu2XirMkbWe
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.

1 participant