Skip to content

chore: replace ESLint with oxlint#2641

Open
joyenjoyer wants to merge 4 commits into
masterfrom
instui-5035-oxlint-migration
Open

chore: replace ESLint with oxlint#2641
joyenjoyer wants to merge 4 commits into
masterfrom
instui-5035-oxlint-migration

Conversation

@joyenjoyer

@joyenjoyer joyenjoyer commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add .oxlintrc.json (root + regression-test) porting the existing ESLint ruleset to oxlint's native plugins, its alpha jsPlugins bridge for 5 eslint-plugin-react rules oxlint lacks natively, and two custom rules (no-relative-imports, notice) reimplemented for oxlint's JS-plugin API
  • Wire oxlint into lint-staged, ui-scripts lint, and regression-test's lint script; remove ESLint's config files, its superseded custom plugin, and 11 now-unused dependencies. eslint-plugin-react and read-package-up are kept, since both are still runtime deps of oxlint's jsPlugins bridge and custom rules.
  • Fix 2 eslint-disable comments whose rule names didn't match oxlint's actual rule IDs and had silently stopped suppressing anything; delete 6 more that are genuinely dead under oxlint's role-has-required-aria-props implementation
  • Relocate ui-scripts' lint.ts out of a legacy lib/test/ folder into lib/commands/, alongside the other command modules

Test Plan

  • No manual verification needed; covered by existing tests. tsc -b, vitest, and a full-repo oxlint dry run all confirmed clean (only 5 pre-existing, unrelated no-undef errors remain in ui-icons's .cjs configs, unchanged from before this PR).

Fixes INSTUI-5035

🤖 Generated with Claude Code

@joyenjoyer joyenjoyer self-assigned this Jul 15, 2026
@joyenjoyer
joyenjoyer marked this pull request as ready for review July 15, 2026 13:44
@joyenjoyer
joyenjoyer force-pushed the instui-5035-oxlint-migration branch from 435bcbb to 65cacf4 Compare July 15, 2026 14:18
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://instructure.design/pr-preview/pr-2641/

Built to branch gh-pages at 2026-07-16 09:03 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions

Copy link
Copy Markdown

Visual regression report

No changes.

Status Count
Unchanged 32
Changed 0
New 0
Removed 0

📊 View full report

Baselines come from the visual-baselines branch. They refresh on every merge to master.

github-actions Bot pushed a commit that referenced this pull request Jul 15, 2026
@joyenjoyer
joyenjoyer force-pushed the instui-5035-oxlint-migration branch from 65cacf4 to b1a8614 Compare July 15, 2026 14:36
…older

Move lint.ts from lib/test/ into lib/commands/, alongside the other yargs
command modules (bump.ts, server.ts, etc.) it is registered with in
commands/index.ts. The test/ directory is a leftover name from when
ui-scripts absorbed the separate ui-test package.
Add .oxlintrc.json (workspace root and regression-test), porting the
ESLint ruleset to oxlint and covering gaps with two custom rules and a
jsPlugins bridge:

- react-js/* (jsPlugins bridge to eslint-plugin-react): covers no-deprecated, prop-types, no-typos,
  require-default-props, forbid-foreign-prop-types, missing from oxlint's native react plugin.
- instructure/no-relative-imports (custom): blocks relative imports that reach into another
  package's src, bypassing that package's public API.
- notice/notice (custom): requires the MIT license header at the top of source files.
- vitest/valid-expect (override, ui-truncate-text only): disabled because oxlint's vitest plugin
  does not recognize the chai-style assertions used in those tests.

Nothing consumes oxlint yet. ESLint still runs via lint-staged,
ui-scripts lint, and regression-test's lint script.
Wire oxlint into lint-staged, ui-scripts lint, and regression-test's
lint script, replacing ESLint everywhere it ran.

Remove ESLint's config files, its now-superseded custom plugin, and
every dependency with no remaining consumer: eslint, @eslint/js,
@vitest/eslint-plugin, eslint-config-prettier,
eslint-import-resolver-node, eslint-module-utils, eslint-plugin-compat,
eslint-plugin-jsx-a11y, eslint-plugin-notice, globals, and
typescript-eslint.

Keep eslint-plugin-react and read-package-up: both are still runtime
dependencies of oxlint's jsPlugins bridge and custom rules,
respectively.
Two disable comments reference rule names that do not match oxlint's
actual rule IDs, so they silently stopped suppressing anything:

- packages/__docs__/globals.ts: @instructure/no-relative-imports -> instructure/no-relative-imports.
  oxlint's custom rule has no @ scope prefix.
- packages/ui-i18n/src/textDirectionContextConsumer.tsx: react/forbid-foreign-prop-types ->
  react-js/forbid-foreign-prop-types. The bridged eslint-plugin-react is aliased react-js.

Delete 6 jsx_a11y/role-has-required-aria-props disable comments in
TreeBrowser's TreeCollection (v1 and v2):

- oxlint's rule does not require aria-selected for the treeitem role at all, unlike e.g. checkbox,
  which requires aria-checked, so there was nothing for these comments to suppress.

oxlint accepts both jsx-a11y/* and jsx_a11y/* spellings for disable
comments, so the unrelated jsx-a11y/* comments in Checkbox, FileDrop,
Img, NumberInput, and RadioInput needed no change.

Also trims a trailing space in one ColorPreset test title, an
unrelated vitest/valid-title auto-fix.
@joyenjoyer
joyenjoyer force-pushed the instui-5035-oxlint-migration branch from b1a8614 to 1429aaf Compare July 16, 2026 08:58
@joyenjoyer
joyenjoyer requested review from HerrTopi and balzss July 16, 2026 14:41
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