Skip to main content
Logo
Overview

TypeScript 7.0 in Go: Should You Upgrade Now? (tsgo Guide)

June 21, 2026
9 min read

The thing that finally got my attention wasn’t the 10x number. It was a throwaway line in the RC announcement: VS Code’s own type-check dropped from 77 seconds to about 7. That’s Microsoft dogfooding the new compiler on one of the largest TypeScript codebases on the planet, and the result is the difference between “go get coffee” and “blink.”

TypeScript 7.0 hit Release Candidate on June 18, 2026, and the headline is that the compiler is no longer written in TypeScript. It’s written in Go. Microsoft started this under the codename Project Corsa back in March 2025, and the RC is the first build they’re calling suitable for broad production evaluation. GA is expected roughly a month out — an estimate, not a promise.

So the real question for anyone shipping TypeScript today: do you jump now, or wait? The answer depends almost entirely on whether you touch the compiler API. Let me walk through what actually changed, what breaks, and how to roll it out without setting your CI on fire.

A port, not a rewrite — and why that distinction matters

The most important word in the whole announcement is “port.” Microsoft did not redesign the type system. They took the existing TypeScript codebase and reimplemented it in Go, preserving the same type-checking semantics. The legacy JavaScript-based codebase has a name now too — Strada — and the Go version is Corsa.

Why does this matter? Because a port means your types check the same way they did before. The same code that errored under tsc 6.0 should error under tsgo, and the same code that passed should pass. You’re not signing up for a new dialect of TypeScript. You’re signing up for the same dialect, computed much faster.

That’s a genuinely different risk profile from, say, a major framework upgrade where behavior shifts under you. Most of the migration pain here isn’t “my types are suddenly wrong.” It’s tooling — the ecosystem built on top of the old compiler’s internals.

Where the 10x actually comes from

Microsoft says tsgo runs about 10x faster than TypeScript 6.0, and the speedup has two sources stacked on top of each other.

First, native code. Go compiles to a real binary instead of running on a JavaScript engine, so parsing and checking just execute faster at the metal. Second — and this is the part people miss — shared-memory parallelism. The old compiler was effectively single-threaded for type-checking. tsgo parallelizes parsing, checking, and emit across worker threads that share memory, which JavaScript couldn’t do cleanly.

You get knobs for that parallelism:

  • --checkers sets how many type-checking workers run. Default is 4.
  • --builders controls how many project-reference builders run at once, which matters for monorepos with lots of composite projects. It multiplies with --checkers, so --checkers 4 --builders 4 can spin up as many as 16 checkers at once.
  • --singleThreaded turns all of that off, which is handy for debugging or a memory-constrained CI runner.

More checkers means more speed on a many-core box, at the cost of memory. That trade matters. If your CI runner has 2GB and 2 vCPUs, cranking checkers won’t help and might OOM you — the same way a docker build falls over when it hits the memory ceiling and gets OOMKilled. Benchmark on the hardware you actually deploy to, not your 16-core laptop.

How to try it without touching your real build

You don’t have to commit to anything to see the numbers on your own repo. The native compiler ships as a separate package so it can live alongside your existing typescript install:

npm install -D @typescript/native-preview

That gives you a tsgo binary. Run it where you’d run tsc:

npx tsgo --noEmit

Then time both and compare:

time npx tsc --noEmit
time npx tsgo --noEmit

A few honest caveats. The “native preview” line publishes nightlies under the tsgo binary name, and that’s a separate distribution path from the RC itself — the RC ships through the normal tsc channel. So depending on which you install, your binary name and exact version will differ. For kicking the tires, the @typescript/native-preview package is the path of least resistance: it won’t touch your existing tsc, and you can delete it in thirty seconds if you don’t like what you see.

Run it against your largest project first, not your smallest. The speedup is roughly proportional to how much work the checker does, so a tiny package won’t show you much. A 200k-line monorepo will.

What breaks: the compiler API gap

Here’s the part that decides your timeline. TypeScript 7.0 does not support the Strada compiler API — the internals that countless tools reach into. And the replacement, the Corsa API, is still a work in progress. A new, stable compiler API isn’t expected until TypeScript 7.1 at the earliest.

If you’ve never imported from typescript in your own code, none of this affects you and you can probably skip to the migration section. But a lot of teams depend on this without realizing it, because their tools do:

  • typescript-eslint with type-aware rules (anything using parserOptions.project) leans on the compiler API. The typescript-eslint team is working on 7.0 support, but full migration is gated on that 7.1 API landing.
  • Custom transformersts-patch, ttypescript, and anything wiring into the emit pipeline — won’t work against Corsa yet.
  • Type-aware Prettier/formatter plugins and codegen tools that walk the type checker programmatically.
  • ts-node / tsx-style runtime setups that hook compilation, depending on how deep they reach.

The official workaround is sane: install both. Keep typescript (6.0 or earlier) for the tools that need the old API, and use tsgo purely for fast type-checking. So your lint and codegen still run on the JS-based compiler while your tsc --noEmit gate gets the speed boost. It’s not elegant — you’re carrying two compilers — but it’s a clean bridge until 7.1 catches the ecosystem up.

My read: if your package.json has type-aware ESLint plus a custom transformer, treat 7.0 as a type-check accelerator only, and plan the full cutover for 7.1.

The TS 6.0 on-ramp you might have skipped

TypeScript 6.0 shipped in March 2026 as the last major release built on the JavaScript codebase, and it was designed as a bridge. If you upgrade straight from 5.x to 7.0, you skip the warnings 6.0 was trying to give you.

6.0 flipped a pile of defaults and deprecations to line up with 7.0:

  • strict: true is now the default, along with module: esnext and a floating target currently sitting at es2025.
  • The default types value is now an empty array instead of “pull in everything from node_modules/@types,” which stops projects from silently dragging in hundreds of declaration files.
  • ES5 output is deprecated — the lowest target is now ES2015. --downlevelIteration is deprecated along with it.
  • --moduleResolution classic is gone, and node (node10) resolution is on its way out in favor of nodenext or bundler. The amd, umd, and systemjs module targets are no longer supported.
  • --baseUrl is deprecated to avoid surprise “lookup root” behavior.

The practical move: bump to 6.0 first, fix the deprecation warnings it surfaces, and only then reach for 7.0. 6.0 still runs the old compiler, so it’s a low-risk place to clean up your tsconfig before the Go switch. Going 5.x straight to 7.0 means eating all of those default changes and the new compiler in one jump, and when something breaks you won’t know which half caused it.

A staged migration playbook

Don’t flip everything at once. The order that’s worked for me on the runtime upgrades I’ve done — same discipline I’d apply to a Python 3.14 free-threaded rollout — goes roughly like this.

1. Audit your dependency on the compiler API first. Grep your repo and your tooling config. Are you running type-aware ESLint? Custom transformers? Codegen that imports from typescript? This audit decides whether 7.0 is a drop-in or a partial adoption. Do it before anything else.

2. Get to 6.0 and clear the warnings. Bump, run the build, fix deprecations. This is your real migration work; the Go switch is almost a non-event by comparison.

3. Add tsgo to CI as a parallel check, not a replacement. Keep your existing tsc gate green and add a second job that runs tsgo --noEmit. Let them run side by side for a week or two. If tsgo ever reports a different result than tsc, that’s a bug worth a repro — and because it’s a port, a mismatch is genuinely surprising and worth reporting upstream.

4. Cut over the type-check gate. Once the parallel job has been quiet for a couple of weeks, make tsgo the source of truth for type-checking and drop the old job. Keep typescript installed if your linters still need it.

5. Move editors over deliberately. The native language service is what powers in-editor IntelliSense, and editor integration is younger than the CLI. Roll it out to a few volunteers before you make it the team default, and keep the stable extension one keystroke away as a rollback.

6. Hold the line on transformers and type-aware lint until 7.1. Run those on the side-by-side typescript install. Don’t force them onto Corsa before the stable API ships — you’ll just fight half-finished integrations.

The rollback story is refreshingly simple at every step. tsgo is a separate binary and a separate package. If it misbehaves, you point your scripts back at tsc and you’re exactly where you started. That alone makes the experiment cheap.

So, now or wait?

Adopt the type-check now if you’re a CLI-and-editor TypeScript shop with no custom transformers and no type-aware lint blocking you. The speedup is real, the semantics are identical, and the rollback is trivial. Running tsgo as a parallel CI gate today costs you almost nothing and tells you a lot.

Wait for 7.1 if your build leans on the compiler API — type-aware ESLint as a hard gate, ts-patch/ttypescript, programmatic codegen. You can still use tsgo to speed up plain type-checking in the meantime, but the full cutover should track the stable Corsa API, not the RC.

And if you’re still on 5.x, the most useful thing you can do this week has nothing to do with Go. Upgrade to 6.0 and clear the deprecation warnings. That’s the work. The Go compiler is the easy part waiting on the other side.

A quick pre-flight before you touch CI: pin the exact version you tested, benchmark --checkers against your actual runner’s memory instead of your laptop’s, and keep the old tsc job around for one more release than you think you need. Cheap insurance.

If you want a five-minute version of all this, go run npm install -D @typescript/native-preview in your biggest repo and time tsgo --noEmit against tsc --noEmit. The number you get back will tell you more about whether this matters to your team than any blog post can.

Sources: Announcing TypeScript 7.0 RC, Announcing TypeScript Native Previews, Progress on TypeScript 7 - December 2025, TypeScript 6.0 Will Be the Last JavaScript-Based Major Release (Socket), @typescript/native-preview (npm)