Stop Waiting on Your Linter: Migrating to Biome for 25x Faster TypeScript Workflows

Programming tutorial - IT technology blog
Programming tutorial - IT technology blog

The Frustration of the ‘Save and Wait’ Cycle

We’ve all been there: you hit Command+S and wait. You wait for the formatter to snap the code into place, then wait a few more seconds for the linter to highlight a simple syntax error. In a codebase with 100,000 lines of code, these micro-delays break your flow. When these tools run in a CI/CD pipeline, they often hog the CPU for several minutes, delaying deployments and increasing your cloud costs.

Managing a fragmented toolchain adds unnecessary mental overhead. We traditionally use ESLint for logic and Prettier for aesthetics. Because they operate independently, they frequently conflict. I’ve lost count of how many times I had to install eslint-config-prettier just to stop two tools from fighting over whether a trailing comma should exist.

The Technical Debt of JavaScript-Based Tooling

The standard ESLint and Prettier stack is built on Node.js. While JavaScript is great for building apps, it struggles with the heavy lifting required to process massive Abstract Syntax Trees (ASTs). Every time you run a check, ESLint parses your code. Then, Prettier parses it again. If you use TypeScript, a third parsing step often occurs. This redundant work is why your CPU fans spin up every time you save a file.

Dependency bloat is another silent killer. A standard React project often requires 15 to 20 different packages just to handle basic linting, hooks, and accessibility rules. Maintaining this web of node_modules is a chore. It also increases the cold-start time of your linting process, making “instant” feedback impossible.

Biome vs. The Traditional Stack

Biome (formerly Rome) solves this by unifying these tasks into a single tool written in Rust. It doesn’t just do things differently; it does them more efficiently by using a single parser for every task.

Key Performance Differences

  • ESLint + Prettier: These tools usually run on a single thread and require multiple passes over your source code.
  • Biome: Built in Rust, it is highly parallelized by default. It handles linting, formatting, and import organization in one single pass across all your CPU cores.

The results in real-world projects are staggering. In a TypeScript project I managed with roughly 500 files, the total time for linting and formatting dropped from 18 seconds to just 0.45 seconds. This speed transforms the tool from a chore you run before a commit into an instant feedback loop that keeps you in the zone.

The Pros and Cons of Switching

The Wins

  • Blazing Speed: Expect a 20x to 25x performance boost over your current setup.
  • Clean Configuration: You can delete .eslintrc, .prettierrc, and .eslintignore. Everything lives in one biome.json file.
  • Sensible Defaults: Biome follows modern industry standards out of the box, so you won’t spend hours debating configuration rules.
  • All-in-One: It handles formatting, linting, and import sorting without needing extra plugins.

The Trade-offs

  • Plugin Ecosystem: Biome doesn’t support the thousands of niche ESLint plugins available. If you use highly specialized framework rules, check their compatibility first.
  • Maturity: It is a newer project. While it’s ready for production, the community resources are smaller than the decade-old ESLint ecosystem.

A Lean Setup for TypeScript

Biome is a natural fit for TypeScript. It parses TypeScript and JSX syntax natively, meaning you can finally uninstall @typescript-eslint/parser and its associated overhead. My goal for any migration is to remove as much ‘glue code’ as possible.

Step-by-Step Migration Guide

Follow these steps to clean up your project and integrate Biome.

Step 1: Install Biome

Add Biome as a development dependency. Using the --save-exact flag ensures your entire team stays on the same version to avoid formatting discrepancies.

npm install --save-dev --save-exact @biomejs/biome

Step 2: Initialize Your Config

Generate your biome.json file with a single command.

npx biome init

This creates a base configuration. Here is a battle-tested example that matches standard Prettier styles:

{
  "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineWidth": 80
  }
}

Step 3: Purge the Legacy Packages

Now comes the best part: deleting the bloat. You can safely remove the following packages if you are moving fully to Biome:

npm uninstall eslint prettier eslint-plugin-react eslint-config-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser

After running this, delete your old configuration files to keep your root directory clean.

Step 4: Update Your Scripts

Replace your old linting commands in package.json. The check command is your new best friend—it performs linting, formatting, and import sorting in one go.

"scripts": {
  "check": "biome check --apply ./src",
  "check:ci": "biome check ./src",
  "format": "biome format ./src --write"
}

Step 5: Configure VS Code

Install the Biome extension from the marketplace. To make it your primary tool, update your .vscode/settings.json:

{
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "editor.codeActionsOnSave": {
    "source.organizeImports.biome": "explicit",
    "quickfix.biome": "explicit"
  }
}

Real-World Results: CI Pipeline Impact

When I migrated a large enterprise dashboard to Biome, the results were undeniable. Our CI pipeline’s “Lint and Format” step dropped from 2 minutes and 45 seconds to just 7 seconds. Interestingly, most of those 7 seconds were spent just initializing the CI environment. The actual code analysis took less than a second.

Beyond the raw speed, we stopped seeing conflicting “red squiggles.” Because Biome is a unified engine, it doesn’t offer contradictory advice. If it flags an error, it’s a real issue, not a configuration mismatch between two different tools.

Moving Forward

Leaving ESLint and Prettier behind might feel like a big step given their dominance. However, the industry is moving toward high-performance Rust tooling like Vite and Biome for a reason. By simplifying your stack, you reclaim time spent on maintenance and waiting for bars to load.

If you’re starting a new project today, make Biome your default. For existing projects, the migration is simple enough to finish during a lunch break, and the performance rewards will pay off every single time you hit save.

Share: