Skip to content

chore(eslint): upgrade ESLint 8 → 9 with flat config migration#497

Merged
curfew-marathon merged 6 commits into
mainfrom
chore/eslint-9-upgrade
Jun 15, 2026
Merged

chore(eslint): upgrade ESLint 8 → 9 with flat config migration#497
curfew-marathon merged 6 commits into
mainfrom
chore/eslint-9-upgrade

Conversation

@curfew-marathon

Copy link
Copy Markdown
Contributor

Upgrades ESLint from 8.57.1 to 9.x and migrates from the legacy .eslintrc.js format to ESLint 9's flat config (eslint.config.mjs).

Package changes

  • eslint: ^8.57.1 → ^9.0.0
  • Removed @typescript-eslint/eslint-plugin and @typescript-eslint/parser (replaced by the typescript-eslint meta-package which bundles both)
  • Removed eslint-plugin-import (replaced by eslint-plugin-import-x, a maintained ESLint 9 / flat-config-first fork)
  • Added @eslint/js ^9.0.0 (provides js.configs.recommended for flat config)
  • Added typescript-eslint ^8.0.0 (meta-package with tseslint.config() helper)
  • Added eslint-plugin-import-x ^4.0.0
  • Added globals ^15.0.0 (replaces the env: block removed in ESLint 9)

Config migration

Deleted .eslintrc.js and .eslintignore. All config is now in eslint.config.mjs using ESLint 9 flat config format:

  • ignores: replaces .eslintignore and ignorePatterns
  • languageOptions.globals: replaces env: { browser, es2021, node }
  • languageOptions.parserOptions: replaces top-level parserOptions
  • extends via tseslint.config(): replaces the extends array
  • All existing rules are preserved with identical severity levels

Resolution-dependent import-x rules (no-unresolved, namespace, named) are disabled — the TypeScript compiler already validates module resolution for this extension, making those checks redundant. The same approach was used with the old eslint-plugin-import/typescript config.

CI fixes

  • Removed --ignore-path .galintignore from the lint step in main.yaml (flag removed in ESLint 9; the file never existed anyway)
  • Removed --ext .ts,.tsx from the lint script in package.json (file extensions are now controlled by the files glob in the config)

Dependabot

Removed eslint from exclude-patterns in all three npm package ecosystems so Dependabot will track the new ESLint 9 packages going forward.

Source files

Removed 7 stale // eslint-disable-next-line import/no-unresolved inline comments from client/src. These referenced the old plugin prefix (import/ not import-x/) and caused ESLint 9 to error with "Definition for rule not found". The rule is disabled globally in the new config so the inline directives were no longer needed regardless.

Description

What problem is being solved?

How is it being solved?

What changes are made to solve it?

References

Review Checklist

  • I have clicked on "allow edits by maintainers".
  • I have added documentation for new/changed functionality in this PR or in a PR to openfga.dev [Provide a link to any relevant PRs in the references section above]
  • The correct base branch is being used, if not main
  • I have added tests to validate that the change in functionality is working as expected

Upgrades ESLint from 8.57.1 to 9.x and migrates from the legacy
.eslintrc.js format to ESLint 9's flat config (eslint.config.mjs).

## Package changes

- eslint: ^8.57.1 → ^9.0.0
- Removed @typescript-eslint/eslint-plugin and @typescript-eslint/parser
  (replaced by the typescript-eslint meta-package which bundles both)
- Removed eslint-plugin-import (replaced by eslint-plugin-import-x, a
  maintained ESLint 9 / flat-config-first fork)
- Added @eslint/js ^9.0.0 (provides js.configs.recommended for flat config)
- Added typescript-eslint ^8.0.0 (meta-package with tseslint.config() helper)
- Added eslint-plugin-import-x ^4.0.0
- Added globals ^15.0.0 (replaces the env: block removed in ESLint 9)

## Config migration

Deleted .eslintrc.js and .eslintignore. All config is now in
eslint.config.mjs using ESLint 9 flat config format:

- ignores: replaces .eslintignore and ignorePatterns
- languageOptions.globals: replaces env: { browser, es2021, node }
- languageOptions.parserOptions: replaces top-level parserOptions
- extends via tseslint.config(): replaces the extends array
- All existing rules are preserved with identical severity levels

Resolution-dependent import-x rules (no-unresolved, namespace, named)
are disabled — the TypeScript compiler already validates module
resolution for this extension, making those checks redundant. The same
approach was used with the old eslint-plugin-import/typescript config.

## CI fixes

- Removed --ignore-path .galintignore from the lint step in
  main.yaml (flag removed in ESLint 9; the file never existed anyway)
- Removed --ext .ts,.tsx from the lint script in package.json
  (file extensions are now controlled by the files glob in the config)

## Dependabot

Removed eslint from exclude-patterns in all three npm package
ecosystems so Dependabot will track the new ESLint 9 packages going
forward.

## Source files

Removed 7 stale `// eslint-disable-next-line import/no-unresolved`
inline comments from client/src. These referenced the old plugin prefix
(import/ not import-x/) and caused ESLint 9 to error with "Definition
for rule not found". The rule is disabled globally in the new config so
the inline directives were no longer needed regardless.
Copilot AI review requested due to automatic review settings March 30, 2026 17:26
@curfew-marathon
curfew-marathon requested a review from a team as a code owner March 30, 2026 17:26
@socket-security

socket-security Bot commented Mar 30, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedtypescript-eslint@​8.61.01001007498100
Addedeslint-plugin-import-x@​4.16.29910010082100
Updatedglobals@​13.24.0 ⏵ 15.15.010010085 +190100
Updated@​eslint/​js@​8.57.1 ⏵ 9.39.4100100100 +1488100
Updatedeslint@​8.57.1 ⏵ 9.39.497 +110010097 +47100

View full report

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.

Pull request overview

Upgrades the repo’s linting toolchain to ESLint 9 and migrates from legacy .eslintrc.js / .eslintignore to ESLint’s flat config (eslint.config.mjs), along with related CI and Dependabot adjustments.

Changes:

  • Bump ESLint to ^9.0.0, switch to typescript-eslint meta-package, and replace eslint-plugin-import with eslint-plugin-import-x.
  • Add eslint.config.mjs flat config (including ignores, globals, and preserved rules) and remove legacy config/ignore files.
  • Update CI lint invocation and Dependabot grouping rules; remove now-stale inline eslint-disable directives in client sources.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
package.json Updates lint script and devDependencies for ESLint 9 + flat config tooling.
package-lock.json Lockfile refresh for updated ESLint ecosystem packages.
eslint.config.mjs Introduces ESLint 9 flat config with TS + import-x + prettier integration.
client/src/test/hover.test.ts Removes stale inline eslint-disable-next-line import/no-unresolved.
client/src/test/helper.ts Removes stale inline eslint-disable-next-line import/no-unresolved.
client/src/test/extension.test.ts Removes stale inline eslint-disable-next-line import/no-unresolved.
client/src/test/diagnostics.test.ts Removes stale inline eslint-disable-next-line import/no-unresolved.
client/src/extension.node.ts Removes stale inline eslint-disable-next-line import/no-unresolved.
client/src/extension.common.ts Removes stale inline eslint-disable-next-line import/no-unresolved.
client/src/extension.browser.ts Removes stale inline eslint-disable-next-line import/no-unresolved.
.github/workflows/main.yaml Simplifies lint step to npm run lint (drops ignore-path flag).
.github/dependabot.yaml Removes eslint exclusion so Dependabot can track ESLint-related packages.
.eslintrc.js Deletes legacy ESLint config in favor of flat config.
.eslintignore Deletes legacy ESLint ignore file in favor of flat config ignores.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread package.json
Comment thread eslint.config.mjs
The file was only consumed by --ignore-path .galintignore in the CI
lint step, which was removed as part of the ESLint 9 migration.
client/src/test/diagnostics.test.ts now passes lint cleanly so the
exclusion is no longer needed.

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.

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@curfew-marathon
curfew-marathon added this pull request to the merge queue Jun 15, 2026
Merged via the queue into main with commit 37a5add Jun 15, 2026
13 of 16 checks passed
@curfew-marathon
curfew-marathon deleted the chore/eslint-9-upgrade branch June 15, 2026 18:48
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