-
Notifications
You must be signed in to change notification settings - Fork 1.7k
chore(frontend): Migrate from 🐌 ESLint to ⚡ Oxlint #33714
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Summary
Major migration from ESLint to Oxlint for frontend linting, delivering a 97% reduction in linting time (from ~8s to ~200ms per file) while preserving most code quality rules.
- Removed
.eslintrc.js
and custom ESLint rules in favor of.oxlintrc.json
with built-in equivalents - Preserved key rules through Oxlint built-ins:
no-schema-index-import
→no-restricted-imports
,no-spread-in-reduce
→no-accumulating-spread
- Removed deprecated
warn-elements
rule as Ant Design → Lemon UI migration is complete - Simplified React component exports by standardizing memo wrapper usage and function naming
- Sacrificed
no-survey-string-constants
custom rule as it cannot be replicated in Oxlint
41 files reviewed, 4 comments
Edit PR Review Bot Settings | Greptile
frontend/src/lib/components/TaxonomicFilter/taxonomicFilterLogic.test.ts
Show resolved
Hide resolved
This is gonna be my PR of the year 😍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, new toy! I trust this works
More eggs to be crackedI neglected to mention two aspects in the PR description. Missing pluginsOxlint supports a rich set of rules from the most important ESLint plugins, but it doesn't supports other plugins. Here are the ones we have to drop:
Rule rigmaroleSome rules work slightly differently, meaning there are new violations. I'm disabling those rules in this PR to keep the diff minimal, and re-enabling in a separate PR:
|
Co-Authored-By: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Size Change: -262 B (-0.01%) Total Size: 2.57 MB ℹ️ View Unchanged
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Amazing 🙌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont like we're losing autofix for imports, but this is just so much nicer, let's do it
We should keep an eye out for an improved version of it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file can go now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, removed
Problem
Any commit to the PostHog frontend is painful. Here's how long it takes to lint a staged TypeScript file, as part of the pre-commit hooks:
7-8 s to lint a single file. For the whole codebase: practically the same - there's insane overhead.
7-8 s to get any feedback whether the commit will go through, or if there's one more error to go back to and fix.
From my earlier tests, almost all this latency is in
typescript-eslint/parser
. To lint just one file, it parses the whole codebase, and not particularly fast. I've been trying to find ways to optimize that while still using ESLint. There are none.Only two possible solutions:
Changes
@mariusandra and @adamleithp are working towards the frontend codebase being split up, but the parts of the code are tangled to a level preventing that linting optimization. It'll take weeks or months just to split each product into its own product folder.
But, of course someone has rewritten ESLint in Rust. The folks from Vite and Vitest made
oxlint
. Oxlint just hit 1.0, and now is a drop-in replacement for ESLint.What if we try it, with all the same rules we've had in ESLint?
~200 ms to lint one file. (Whole codebase: 600 ms.)
For human intents and purposes, this makes pre-commit feedback instant.
Caveats
To make an omelette you have to crack a few eggs.
Oxlint doesn't support custom rules, so I had to work around out that. Rule by rule:
posthog/no-schema-index-import
– ✅ built into ESlint and Oxlint, ruleno-restricted-imports
(@rafaeelaudibert)posthog/no-spread-in-reduce
– ✅ built into Oxlint, ruleno-accumulating-spread
(it's actually much more robust, so much that it's caught many more violations that we should fix, hence I'll enable it in a separate PR @benjackwhite)posthog/warn-elements
– 🗑️ same asreact/forbid-elements
, we only used it to have a secondreact/forbid-elements
config with level "warn" instead of "error", for the Ant Design → Lemon UI migration – but this is no longer neededposthog/no-survey-string-constants
–How did you test this code?
pnpm oxlint --quiet
No changes other than formatting here.