The TypeScript 7.0 Migration Recipe: Switching to the Go Compiler Without Breaking Your App
TL;DR: TypeScript 7.0 (released July 8, 2026) replaces the JavaScript-based compiler with a native Go port that is 8-12x faster on full builds. If your project already compiles cleanly on TS 6.0, the upgrade is
npm install -D typescript@latestplus an editor extension. The real danger is not your code; it's your tooling. 7.0 ships without a compiler API, so typescript-eslint, ts-morph,tsup --dts, and the Vue/Astro/Svelte ecosystem stay pinned to TS 6 until the new compiler API lands (planned for 7.1) and the framework tooling adopts it.

Photo by Roberto Nickson on Unsplash
Four months ago, I wrote the TypeScript 6.0 migration recipe and ended it with a promise: do the boring config work now, and when 7.0 drops, you'll be the one drinking coffee while everyone else is putting out fires.
Well. TypeScript 7.0 went stable on July 8, 2026. Time to collect.
If you followed the 6.0 recipe (explicit rootDir, explicit types, strict mode either fixed or consciously opted out of), I have good news: your 7.0 migration is mostly a version bump and a very satisfying look at your new build times. Microsoft's own line is that practically any code that compiles cleanly on 6.0 compiles identically on 7.0.
If you skipped 6.0 and are jumping straight from 5.x… you're now doing two migrations at once, one of which no longer prints warnings before failing. I'll cover you too, but you're reading the recipe in the wrong order and we both know it.
One thing before we start: your code is the easy part of this migration. Your tooling is where the bodies are buried. More on that in section 4, and do not skip it.
- 1. What Actually Changed: tsc Is Now a Go Binary
- 2. The Upgrade Itself: 15 Minutes If You Did Your Homework
- 3. Breaking Changes: The Short List
- 4. The Tooling Minefield: No Compiler API Until 7.1
- 5. The Payoff: Numbers and New Knobs
- 6. Time Expectation & Decision Guide
- References & Further Reading
1. What Actually Changed: tsc Is Now a Go Binary
This is not a feature release. TypeScript 7.0 is the same language, the same type system, and (deliberately) almost the same behavior. But the compiler that checks your code is no longer JavaScript running on Node. It's a native Go binary, ported line by faithful line from the original codebase under the name Project Corsa.
What native code plus shared-memory multithreading buys you:
- 8-12x faster full builds. VS Code's 1.5M-line codebase: 125.7s → 10.6s. Sentry: 139.8s → 15.7s. Bluesky: 24.3s → 2.8s.
- Editor project load dropped from ~17.5 seconds to under 1.3 seconds on large codebases.
- 6-26% less memory, depending on the codebase.
- A rebuilt
--watchmode based on Parcel's file watcher. The old polling-related weirdness on Windows and network drives is gone. - A full LSP-based language server, with Microsoft reporting 80% fewer failing commands and 60% fewer crashes than the TS 6 server.
The part that matters for your migration: tsc on your PATH is now the Go binary (you'll see it called tsgo in older preview docs). Same CLI, same tsconfig.json, same diagnostics. Different engine.
2. The Upgrade Itself: 15 Minutes If You Did Your Homework
No migration script this time. TS 6.0 was the migration script. The recipe:
npm install -D typescript@latest
npx tsc --noEmitIf you're on a clean 6.0 config, that second command should produce the same output as before, just suspiciously fast. Fast enough that the first run genuinely looks like it crashed before finishing. It didn't. It's just done.
Then wire up your editor:
- VS Code: install the official "TypeScript 7" extension. Until you do, IntelliSense still runs on the old TS 6 server while your builds run on 7, a fun source of "works in the editor, fails in CI" ghosts.
- Visual Studio: the latest Visual Studio enables it automatically.
- JetBrains IDEs: you can point WebStorm and the other JetBrains IDEs directly at
typescript@7to get the new language server. The catch is the embedded-language plugins (Vue, Astro, Svelte, Angular templates), which keep relying on TS 6 until they adopt the new API.
If you want a paranoia buffer before committing, run both compilers side by side. The official @typescript/typescript6 package ships a tsc6 binary for exactly this:
npm install -D typescript@latest @typescript/typescript6
# CI: both must agree
npx tsc --noEmit && npx tsc6 --noEmitRun it for a week or two before you commit. Once the outputs match consistently, drop the second compiler and move on.
3. Breaking Changes: The Short List
Everything TS 6.0 shipped as a deprecation warning is now simply gone. If your 6.0 build was warning-free, this table is a formality. If you're jumping from 5.x, this table is your afternoon.
| What | TS 6.0 behavior | TS 7.0 behavior |
|---|---|---|
target: "es5" |
Deprecation error | Removed; minimum is ES2015 |
module: AMD / UMD / SystemJS / none |
Deprecated | Removed |
moduleResolution: "node" (node10) |
Deprecated | Removed; use "bundler" or "nodenext" |
downlevelIteration |
Deprecated | Removed |
strict |
true by default |
true by default (unchanged) |
types |
[] by default |
[] by default (unchanged) |
rootDir |
tsconfig folder | ./; set it explicitly |
The greatest hits, for those arriving late:
strict: true: Still the Default, Still Non-Negotiable
- Question: Did I ever explicitly set
strictin my config, or was I coasting on the oldfalsedefault? - Context: Same deal as 6.0. Omit it and you get all strict checks, including
strictNullChecksandnoImplicitAny. - Fix: Fix the types, or explicitly set
"strict": falseand write the tech-debt ticket. The compiler no longer negotiates.
rootDir and types: The Two Explicit Settings That Save You
- Question: Is my
dist/output landing where my Dockerfile thinks it is, and doesprocessstill exist as far as the compiler is concerned? - Context: Both defaults changed in the 6.0 era. If you see
Cannot find name 'process'or your output shifted todist/src/, these are the culprits. - Fix:
{
"compilerOptions": {
"rootDir": "./src",
"types": ["node", "jest"]
}
}JSDoc Users: Your Turn to Feel Something
- Question: Do I type-check plain
.jsfiles with JSDoc annotations? - Context: The Go compiler aligns JSDoc analysis strictly with TypeScript's. Several Closure-era patterns are gone:
@enum, standalone?as a type,@classconstructor functions, postfix!, and Closure-style function syntax. Type names now require proper@typedeftags. - Fix: Modernize the annotations, or admit it's 2026 and rename the file to
.ts.
// Gone in TS 7.0
/** @enum {string} */
const Status = { ACTIVE: "active", DONE: "done" };
// Works: real code instead of comment folklore
/** @typedef {"active" | "done"} Status */4. The Tooling Minefield: No Compiler API Until 7.1
Here's the part the "10x faster!!" posts conveniently compress into a footnote: TypeScript 7.0 ships without a compiler API.
The old Strada API (everything you got from import * as ts from "typescript") does not exist in the Go compiler. A new (and different) API is planned for TypeScript 7.1. Until then, every tool that programmatically pokes at the type checker is stuck on TS 6:
| Tool | Status on 7.0 |
|---|---|
| Vite 6+ (esbuild transpile) | ✅ Usually fine; it never touched the API |
tsup without --dts |
✅ Works |
tsup --dts |
❌ Broken; needs the API |
| typescript-eslint | ❌ Pin to TS 6 (or try oxlint + tsgolint: already covers dozens of type-aware rules and is much faster, but still relatively young) |
| ts-morph | ❌ Broken, full stop |
| ts-jest | ❌ Keep it on TS 6 |
| Webpack | ⚠️ Depends on the loader (see below) |
| Vue / Astro / Svelte / MDX / Angular templates | ❌ Embedded-language tooling stays on TS 6 until the new API lands and the plugins adopt it |
A word on bundlers, from my own experience rather than the release notes: if your build relies on esbuild or SWC for transpilation and you run tsc --noEmit separately for type-checking, you're generally unaffected. Those transpilers never touched the type checker. The trouble starts when a loader or plugin directly imports typescript to do its own type work, ts-loader in its type-checking mode being the classic example. If that's your setup, either move type-checking to a standalone tsc --noEmit step or keep that one loader pinned to TS 6.
The escape hatch is the @typescript/typescript6 package from section 2: TS 7 as your compiler, TS 6 as a library for the tools that still need the old API.
// package.json
{
"devDependencies": {
"typescript": "^7.0.0",
"@typescript/typescript6": "^6.0.0"
}
}Point typescript-eslint and friends at @typescript/typescript6, let tsc (the Go one) do your actual type-checking, and revisit the whole arrangement once 7.1 ships the new API and the tools adopt it.
My take: this is a reasonable trade and an annoying one at the same time. Shipping the compiler without the API kept 7.0 from slipping another year, but it means "we're on TypeScript 7" and "our entire toolchain is on TypeScript 7" are two different sentences for a while. Budget accordingly.
If you maintain a Vue or Astro codebase: don't force it. Your language tooling literally cannot use 7.0 yet. Stay on 6.0, keep your config clean, and check back once the new API lands and your framework's plugins adopt it. That's not cowardice; that's reading the release notes.
5. The Payoff: Numbers and New Knobs
Assuming you made it through the minefield, here's what you actually get.
The build times are not marketing. On a mid-size Node + React monorepo, a full tsc --noEmit that used to run in the tens of seconds now finishes in a handful. CI type-check goes from "go get coffee" to "don't even alt-tab." The 8-12x range Microsoft quotes holds up on real projects, not just their benchmark suite.
New parallelization flags worth knowing:
--checkers: number of parallel type-checking workers (default: 4). On a beefy CI runner, raising this is free speed.--builders: parallelizes project-reference builds in monorepos.--singleThreaded: disables all parallelism. Useful for bisecting weird behavior or running on tiny containers.
# Monorepo full build on an 8-core runner
tsc --build --checkers 8 --builders 4The watch mode is finally boring, in the best sense. The Parcel-based watcher picks up renames, branch switches, and mass file changes without the occasional stale-state restart ritual the old watcher trained us all to perform.
The editor is the sleeper feature. Sub-1.3-second project loads change behavior in ways raw build numbers don't. Rename-symbol on a large codebase is instant. "Find all references" is instant. You stop scheduling your refactors around the language server, and that's worth more than the CI savings.
6. Time Expectation & Decision Guide
- You did the TS 6.0 migration, modern stack, no API-dependent tooling: ~15 minutes. Bump, extension, done. This is your reward, so enjoy it, you earned it.
- You did TS 6.0 but use typescript-eslint / ts-jest / tsup --dts: half a day. The compiler bump is trivial; wiring in
@typescript/typescript6and verifying CI is the work. - You're on 5.x: stop. Do the TS 6.0 recipe first, because it surfaces every 7.0 breaking change as a warning instead of a hard error. Going straight from 5.x to 7.0 means debugging removals with no deprecation messages to guide you.
- Vue / Astro / Svelte / heavy Compiler-API usage: stay on 6.0 until the new compiler API lands (planned for 7.1) and your framework tooling adopts it. Set a calendar reminder, not a Jira epic.
The pattern from the 6.0 article held: TypeScript major migrations are paid in advance or paid with interest. 6.0 was the invoice. 7.0 is the delivery.
And for once, the delivery is a compiler that finishes before you've finished reaching for your coffee.
I'm generally the kind of person who likes to dive deep into technology, understand it from the inside, and get better at it. When I find something that clarifies a tricky upgrade or saves time, I share it in the hope it helps others move a bit faster and worry a bit less about the tooling.
References & Further Reading
- Announcing TypeScript 7.0: The official release post, with benchmarks, the new parallelization flags, and the fine print on the missing API.
- TypeScript 7: Go Compiler, Breaking Changes, Migration Guide: A solid independent breakdown with a detailed tooling compatibility matrix.
- The TypeScript 6.0 Migration Recipe: My previous article, and the prerequisite for this one if you're still on 5.x.