index

Why We Migrated 6,000+ TypeScript Files from ESLint to oxlint

TL;DR: ESLint was getting too slow for our 6,000+ files React + TS codebase. I found oxlint. Consulted the team, got buy-in, and shipped it. ~50× faster feedback. In the age of AI-generated code I think keeping code quality high matters more than ever. Also made my first contribution to the OXC project. Rust-based JS tooling is the future.

The problem

We have over 6,000 TypeScript React files on our main frontend with pre-commit hooks running lint and formatting on staged files. The more files staged, the slower it gets. It had gotten slow enough that developers were skipping it. Myself included. CI builds? Don’t even ask.

AI coding tools make this worse. It’s gotten to the point where agents will just run git commit --no-verify because the hook takes too long and they don’t feel like fixing the ESLint issues. Sure we can add rules or configs to prevent that, but I still have trust issues with agents actually following those rules and configs consistently. I tried getting Copilot to use ast-grep instead of grep, explicitly. It fell back to grep. Multiple times. Maybe skill issue 🤷🏻‍♂️ but I’d rather not bet code quality on it. This kind of thing needs to be more deterministic.

Enter oxlint

oxlint is part of the OXC project which sits under VoidZero, the same org behind Vite and Rolldown (the fastest JS bundler, written in Rust). Their mission is making JavaScript developers more productive. Everything in OXC is written in Rust.

I went down the rabbit hole. Read the docs, then started reading the source. If you know me, you know I love working with Rust and I enjoy reading it just as much. I spend my free time contributing to open source written in Rust even though my day job is mostly JS and TS. I found a way to contribute (they have good first issues for porting linter rules) and I did: PR. Great docs, easy to get started, welcoming maintainers, well-structured codebase. Genuinely one of the best open source experiences I’ve had.

Back to the main point, most ESLint rules are already well supported in oxlint. I analyzed our codebase, weighed the tradeoffs on the rules that weren’t ported yet, and it was a clear win. The migration was even easier with AI assistance, took a day. Removed all the extra ESLint plugins too, so now it’s a single dependency. I love when I remove things.

The result

~50× faster. Imagine 1 second for 6,000 files in a normal CI pipeline.

The bigger picture

We’re at an interesting moment. Producing code is cheap now but keeping it high quality is going to get expensive fast if we don’t learn to harness that properly. I believe more deterministic tooling for code quality is a must-have in the AI-assisted coding age, not a nice-to-have.

Rust-based JS tooling is only going to gain more traction from here. Excited for what’s coming and hopefully I can keep contributing as well.