Back to BlogTypeScript

TypeScript 7 Made Your Builds 10x Faster and Took ESLint With It

TypeScript 7's Go port deleted the programmatic compiler API, so typescript-eslint, ts-jest, ts-morph and vue-tsc all stopped working on it. The 7.1 beta that restores the API was slated for October 6 and is still landing. Here is what actually breaks, why npm blocks the install before your code does, and the two compiler setup that gets you the fast typecheck without giving up lint rules.

TypeScriptTypeScript 7ESLintToolingMonorepo
TypeScript 7 Made Your Builds 10x Faster and Took ESLint With It

The Go port of the TypeScript compiler went GA on July 8, and the numbers were not marketing. Microsoft measured a full build of the VS Code codebase dropping from 125.7 seconds to 10.6 seconds, with aggregate memory down roughly 18 percent. Every team I've heard from got the same shape of result. Typecheck went from coffee break to barely noticeable.

Then they ran eslint . and the room got quiet.

TypeScript 7.0 shipped without a stable programmatic compiler API. Not deprecated, not slower, just absent. The 7.1 iteration plan penciled the beta in for October 6 with stable on November 24, and at the start of this month the next tag was still handing out dev builds like 7.1.0-dev.20261001.1. So right now we're sitting in the gap: the fast compiler exists, and half your toolchain can't see it.

What broke, and why it isn't a bug

Anything that does import ts from "typescript" and then pokes at createProgram, getTypeChecker, or the AST is dead on 7.0. That list is longer than people expect.

The port was a port, not a rewrite. Type checking behavior is meant to be identical, and mostly is. But the public API was a JavaScript object graph that tools reached into and mutated, and there is no cheap way to hand a Go process's internal AST to a Node plugin. Rebuilding that boundary properly is the actual work of 7.1, and I'd rather they take the time than ship a half bridge we spend two years unwinding.

Which doesn't make it less annoying. Any lint rule that needs type information goes with it: no-floating-promises, no-unsafe-assignment, await-thenable, the whole reason you turned on typed linting in the first place. The syntax only rules survive because they never needed the checker.

npm stops you before your code does

typescript-eslint 8.71.0 declares typescript as a peer with the range >=4.8.4 <6.1.0. Install TypeScript 7 next to it and you get ERESOLVE on a clean lockfile.

Please do not reach for --legacy-peer-deps here. That peer range is correct. It is the maintainers telling you the package genuinely cannot run against this compiler, and forcing the install just moves the failure from npm i to a stack trace inside ESLint that you'll spend an afternoon misreading. The tracking issue for TS 7 support is #10940 and it has no committed date, which tells you where the dependency actually sits: downstream of 7.1 landing.

Run two compilers on purpose

The practical escape hatch is Microsoft's compatibility package, @typescript/typescript6. It ships a tsc6 executable and re-exports the 6.0 API, which means you can keep the old compiler around purely to feed the tools that need an API, while the Go binary does the job you upgraded for.

In package.json, pin both and override what typescript-eslint resolves:

{
  "devDependencies": {
    "typescript": "7.0.2",
    "@typescript/typescript6": "^6.0.0",
    "typescript-eslint": "8.71.0"
  },
  "overrides": {
    "typescript-eslint": {
      "typescript": "npm:@typescript/typescript6@^6.0.0"
    }
  },
  "scripts": {
    "typecheck": "tsc --noEmit",
    "typecheck:compat": "tsc6 --noEmit",
    "lint": "eslint ."
  }
}

pnpm wants pnpm.overrides with the same nested shape. Yarn uses resolutions. Either way the effect is that two copies of the compiler live in your tree, and yes, that is duct tape. It's duct tape with a known removal date, which is the only kind worth applying.

Keep typecheck:compat in CI for a while. The port is behavior compatible in intent, not in a way anyone should take on faith, and a second opinion from the old checker costs you one parallel job. If the two disagree, TypeScript 6's --stableTypeOrdering makes 6.0 order types the way 7 does, which turns a pile of unrelated looking errors into something diffable. It can slow checking by up to 25 percent, so use it to diagnose and then turn it off.

What I'd do this week

If you're on an app repo with no published types, upgrade now and take the two compiler hit. The build speed is worth real money in CI minutes and the duct tape is three lines of JSON.

If you ship a library, or you're on Vue, Svelte, Astro, or Angular, wait. Those toolchains are all sitting on the same API and you'd be migrating twice.

And if you already upgraded and quietly disabled typed lint rules to make the pipeline green, write that down somewhere visible. Leave a comment in the ESLint config with the date and the issue number. Disabled type aware rules have a way of staying disabled long after the reason expires, and no-floating-promises is not a rule you want to rediscover through a production incident six months from now.

The 7.1 beta was due October 6. Betas slip. Plan for November and be pleasantly surprised.