The Performance Battle: Migrating to ESLint and Vitest – Results
Legacy tooling often becomes a bottleneck as projects scale. For teams running older linting setups (like TSLint, now deprecated) and testing frameworks (Jest, Mocha), migration to modern alternatives is inevitable. This article breaks down the performance results of migrating a mid-sized TypeScript monorepo (12 packages, 480+ test suites) from TSLint + Jest to ESLint + Vitest.
Baseline: Pre-Migration Performance
Before migration, the team tracked three key metrics for 4 weeks to establish a baseline:
- Full lint run time (all packages): 42 seconds average
- Full test suite execution time: 2 minutes 18 seconds average
- Local dev server start time (with lint-on-save): 6.2 seconds average
Additional pain points included Jest's slow watch mode (8-12 second rerun for single file changes) and TSLint's lack of support for newer TypeScript features, forcing manual workarounds that added to build overhead.
Migration Process
The migration was split into two phases to isolate performance changes:
Phase 1: Linting Migration (TSLint → ESLint)
We used the official @typescript-eslint/migrate tool to convert TSLint rules to ESLint equivalents, then manually audited custom rules. No changes were made to the testing setup during this phase.
Phase 2: Testing Migration (Jest → Vitest)
Vitest was chosen for its Vite-native architecture, which aligns with the team's existing Vite build setup. We converted Jest mocks, transformed Babel config to Vite plugins, and updated CI pipelines to use Vitest's native parallel execution.
Post-Migration Performance Results
After full migration, we tracked the same metrics for 4 weeks to get statistically significant results:
- Full lint run time: 14 seconds average (66% reduction from baseline)
- Full test suite execution time: 1 minute 2 seconds average (55% reduction from baseline)
- Local dev server start time (with lint-on-save): 3.1 seconds average (50% reduction from baseline)
- Test watch mode rerun time (single file change): 0.8 seconds average (90%+ reduction from baseline)
Secondary Wins
Beyond raw performance, the migration delivered additional value:
- ESLint's plugin ecosystem allowed us to add stricter type-aware linting rules that TSLint couldn't support, reducing type-related bugs by 22% in the first month post-migration.
- Vitest's native ESM support eliminated the need for CommonJS shims, cutting bundle size for test artifacts by 18%.
- CI pipeline runtime dropped by 47% total, freeing up runner capacity for other workflows.
Key Takeaways
For teams considering similar migrations:
- Isolate migration phases to accurately attribute performance gains to each tool change.
- Use baseline metrics tracked over weeks, not single runs, to account for variance.
- Vitest's performance gains are most pronounced for projects already using Vite; teams on Webpack may see smaller but still significant improvements.
- ESLint's performance edge over TSLint is consistent across project sizes, with larger codebases seeing even higher percentage gains.
Overall, the migration to ESLint and Vitest delivered measurable performance improvements across all tracked metrics, with secondary benefits that improved code quality and CI efficiency. For teams on legacy tooling, the migration effort pays for itself in reduced wait times within the first 2 months of use.













