DEV Community

ANKUSH CHOUDHARY JOHAL
ANKUSH CHOUDHARY JOHAL

Posted on • Originally published at johal.in

The Performance Battle migration with ESLint and Vitest: Results

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:

  1. Isolate migration phases to accurately attribute performance gains to each tool change.
  2. Use baseline metrics tracked over weeks, not single runs, to account for variance.
  3. Vitest's performance gains are most pronounced for projects already using Vite; teams on Webpack may see smaller but still significant improvements.
  4. 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.

Top comments (0)