Skip to content

Switch to TypeScript 7 (tsgo) and replace ESLint with oxlint - #6354

Merged
mstange merged 1 commit into
firefox-devtools:mainfrom
mstange:push-yrnpkqqwltur
Oct 22, 2026
Merged

mstange merged 1 commit into
firefox-devtools:mainfrom
mstange:push-yrnpkqqwltur

Conversation

@mstange

@mstange mstange commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Main | Deploy preview

TypeScript 7 has a faster compiler but eslint isn't compatible with it. But we can switch to oxlint instead; oxlint has many of the lints we use built-in, and for the rest (testing-library, jest-dom) it has a jsPlugin adapter.

Timings on my machine, from a cold cache:

    yarn ts        4.83s -> 1.04s
    yarn lint-js  11.00s -> 1.93s
    yarn lint     14.03s -> 2.98s

Two notes:

  • react/no-did-mount-set-state and react/no-did-update-set-state were already dead. eslint-plugin-react turns them into no-ops for any React >= 16.3, and this project declares 18.0. They stay off.
  • ESLint's no-return-await is deprecated and has no oxlint equivalent. typescript/return-await replaces it in error-handling-correctness-only mode, which reports only where adding or removing await changes which errors a try/catch sees. That is a narrower rule, and it is what found the bug fixed in Add missing await when calling Chrome importer #6346.

The eslint-disable comments for rules loaded through jsPlugins are renamed to the oxlint names.

jsPlugins is documented as alpha and not covered by semver, so an oxlint upgrade may require revisiting this file.

@codecov

codecov Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.78%. Comparing base (7892c63) to head (fe37b88).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6354   +/-   ##
=======================================
  Coverage   84.78%   84.78%           
=======================================
  Files         358      358           
  Lines       38946    38946           
  Branches    11019    11033   +14     
=======================================
  Hits        33022    33022           
  Misses       5488     5488           
  Partials      436      436           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mstange
mstange force-pushed the push-yrnpkqqwltur branch 2 times, most recently from bc43c93 to c197b2c Compare October 8, 2026 19:50
@mstange
mstange marked this pull request as ready for review October 9, 2026 17:46
@mstange
mstange requested review from canova and fatadel as code owners October 9, 2026 17:46

@canova canova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! It looks mostly good to me, I added some comments below.

Also about the top comment of .oxlintrc.json, I'm not a big fan of the old ESLint config references in there. Currently the comment reads more like a migration history. Some things might be worth keeping with some rewording but I would prefer if the migration details live inside the commit message instead. Let me know what you think! Also I think we can trim down the commit message as well.

Comment thread .oxlintrc.json Outdated
Comment thread .oxlintrc.json Outdated
Comment thread .devcontainer/devcontainer.json Outdated
Comment thread src/test/unit/merge-compare.test.ts
Comment thread eslint.config.mjs
Comment thread eslint.config.mjs
Comment thread .oxlintrc.json Outdated
@mstange
mstange force-pushed the push-yrnpkqqwltur branch 2 times, most recently from 59247af to 2bfa865 Compare October 21, 2026 21:05
@mstange
mstange requested a review from canova October 21, 2026 21:06
TypeScript 7 is the native Go port of the compiler. It ships only the
`tsc` binary. Its JavaScript compiler API won't return until 7.1, and
typescript-eslint refuses to load without it. So both switches have to
happen together.

Timings on this machine, from a cold cache:

    yarn ts        4.83s -> 1.04s
    yarn lint-js  11.00s -> 1.93s
    yarn lint     14.03s -> 2.98s

The rules in .oxlintrc.json were derived from the effective configuration
of the old eslint.config.mjs. Every lint category is switched off and each
rule is listed explicitly. Enabling a category would turn on rules that
ESLint didn't enforce.

Rules that oxlint doesn't implement natively come from the original ESLint
plugins, loaded through `jsPlugins` in the same oxlint pass:

    eslint-plugin-testing-library     20 rules
    eslint-plugin-jest-dom            11 rules
    eslint-plugin-react                7 rules, loaded as `react-js`
    eslint-plugin-jest-formatting      padding-around-describe-blocks
    eslint-plugin-import               no-unresolved, for JavaScript files
                                       only, loaded as `import-js`

oxlint implements consistent-return and dot-notation only as type-aware
rules, which can't run on JavaScript files. A small local plugin,
scripts/lib/oxlint-eslint-core-rules.mjs, applies ESLint's own versions
to .js, .mjs and .cjs files.

In TypeScript files, tsc already reports unresolved imports (TS2307).

`eslint` stays a devDependency because these plugins import it. Nothing
runs the ESLint CLI.

These rules are not carried over:

  - no-invalid-this. In TypeScript files, tsc reports the same problem
    (TS2683). ESLint's implementation crashes under oxlint, so it doesn't
    run on JavaScript files. Only one of those uses `this`.
  - react/no-did-mount-set-state and react/no-did-update-set-state.
    eslint-plugin-react makes them no-ops for React 16.3 and newer.
  - no-return-await, which ESLint has deprecated. typescript/return-await
    in `error-handling-correctness-only` mode replaces it. It only reports
    an `await` that changes which errors a surrounding try/catch sees.

Both linters were run over a corpus of 57 files with one defect each, one
per rule. oxlint catches everything ESLint caught, with no false
positives.

eslint-disable comments for jsPlugins rules are renamed to the names
oxlint reports. One jest/no-conditional-expect disable comment is
removed: oxlint's version of the rule misses `function () {}` test
callbacks, so the comment counted as unused. This is
oxc-project/oxc#28054.

@canova canova left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks!

@mstange
mstange added this pull request to the merge queue Oct 22, 2026
Merged via the queue into firefox-devtools:main with commit dfb834b Oct 22, 2026
23 checks passed
@fatadel fatadel mentioned this pull request Oct 22, 2026
fatadel added a commit that referenced this pull request Oct 22, 2026
Changes:

[Markus Stange] Accept more fields from symbolication. (#6373)
[Markus Stange] Support index source maps. (#6399)
[fatadel] Make CompositorScreenshot markers schema-based (#6261)
[Markus Stange] Use inverted transforms in the tests for inverted call node paths. (#6393)
[fatadel] Expose and clear URL-imported call tree search in the CLI (#6387)
[Markus Stange] Make the scrollable editor view in the source view cover the full height of the panel, even if the source code is short. (#6405)
[Nazım Can Altınova] Silence profile loader logs in profile-querier-url tests (#6409)
[Nazım Can Altınova] Add `--js-sources-from-func-names` to `profiler-edit` (#6394)
[Nazım Can Altınova] Look for a source file's address proof in all of its frames (#6407)
[Markus Stange] Some preparations for a function list panel (#6401)
[fatadel] Use fractional seconds with adaptive precision for CLI marker timestamps (#6384)
[fatadel] 🔃 Sync: l10n -> main (October 22, 2026) (#6415)
[Markus Stange] Switch to TypeScript 7 (tsgo) and replace ESLint with oxlint (#6354)
[fatadel] Bump profiler-cli version to 0.12.0 (#6416)

And special thanks to our localizers:

el: Jim Spentzos
uk: Lobodzets, uya2521, Іhor Hordiichuk
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