Skip to content

chore(ui): eslint 10 (via jsx-a11y-x fork)#122

Merged
thejefflarson merged 1 commit into
mainfrom
chore/ui-eslint10-ts7-v2
Jul 23, 2026
Merged

chore(ui): eslint 10 (via jsx-a11y-x fork)#122
thejefflarson merged 1 commit into
mainfrom
chore/ui-eslint10-ts7-v2

Conversation

@thejefflarson

Copy link
Copy Markdown
Owner

Bumps ESLint 9 → 10 for the ui/ package. Supersedes Dependabot #102.

What changed

  • eslint ^9.39.5^10.7.0
  • eslint-plugin-jsx-a11y ^6.10.2removed, replaced by eslint-plugin-jsx-a11y-x ^0.2.0
  • @typescript-eslint/parser ^8.64.0^8.65.0 (already eslint-10-compatible)
  • eslint.config.js migrated to the fork's plugin key (jsx-a11y-x) and config accessor (configs.recommended.rules)

Why the plugin swap

The sole blocker to eslint 10 was eslint-plugin-jsx-a11y@6.10.2: it peer-caps eslint at ^9 and has no eslint 10 release (upstream PRs still open). I verified an npm overrides forcing the peer does work functionally on eslint 10, but chose the cleaner path: eslint-plugin-jsx-a11y-x@0.2.0, a maintained flat-config-native fork whose peer is eslint: ^9 || ^10. Its recommended ruleset is a superset of upstream's — every rule this gate relied on is present (now under a jsx-a11y-x/ prefix), plus label-has-for — so the JEF-431 a11y coverage is unchanged. typescript-eslint and eslint-plugin-react-hooks@7.1.1 already support eslint ^10.

Proof the a11y gate still fires (JEF-431)

A temporary bare-onClick <div> still errors on eslint 10:

jsx-a11y-x/click-events-have-key-events
jsx-a11y-x/no-static-element-interactions
✖ 2 problems (2 errors, 0 warnings)

Gates (all green, local)

  • npm run lint — pass (clean on eslint 10.7.0)
  • npm run build (tsc --noEmit && vite build) — pass
  • npm test (vitest, incl. the axe route-smoke) — 14 passed
  • npm ci — lockfile consistent (CI parity)

TypeScript 7 (#93) is intentionally NOT here

TS 7.0 GA ships the native/Go compiler without a stable programmatic API (that lands in TS 7.1), and typescript-eslint closed the TS-7.0 support request as not planned. I confirmed this empirically: forcing typescript@7.0.2 via an override makes @typescript-eslint/typescript-estree crash at lint time — TypeError: Cannot read properties of undefined (reading 'Cjs') (TS 7 dropped ts.Extension/ts.ModuleKind from its JS surface), which breaks the a11y lint gate. tsc --noEmit/build/test happen to pass under TS 7, but the lint gate does not, and there is no alternative type-aware linter. #93 is infeasible until TS 7.1 — not shipping a masked/broken bump. (Follow-up idea, separate ticket: keep TS 6.x and add @typescript/native-preview for a fast tsgo --noEmit.)

Closes #102

🤖 Generated with Claude Code

https://claude.ai/code/session_01JbrmfzHsTMMzPaSrUkZgWo

Bumps eslint to ^10.7.0. The sole blocker was eslint-plugin-jsx-a11y@6.10.2,
which peer-caps eslint at ^9 and has no eslint 10 release. Swaps it for
eslint-plugin-jsx-a11y-x@^0.2.0, a maintained flat-config-native fork that
supports eslint ^9 || ^10; its recommended ruleset is a superset of upstream's
(same rules under a jsx-a11y-x/ prefix, plus label-has-for), so the JEF-431
a11y gate's coverage is unchanged. Also bumps @typescript-eslint/parser to
^8.65.0 (already eslint-10-compatible).

Proved the a11y gate still fires on eslint 10: a bare-onClick <div> still
errors (jsx-a11y-x/click-events-have-key-events +
jsx-a11y-x/no-static-element-interactions). lint/build/test all green
(incl. the axe route-smoke).

typescript 7 (#93) is intentionally NOT included — see PR body / report.

Closes #102

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JbrmfzHsTMMzPaSrUkZgWo
@thejefflarson
thejefflarson merged commit b5dd8cb into main Jul 23, 2026
4 checks passed
@thejefflarson
thejefflarson deleted the chore/ui-eslint10-ts7-v2 branch July 23, 2026 01:12
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