tsc was never built to exploit cores without tripping over itself. The new tsgo pipeline is explicitly designed to turn “typecheck the monorepo” from a daily outage generator into something you can run on every PR without paying a latency tax.Native compiler foundation (Go) + real parallelism knobs
TypeScript 7.0 Beta is the Go-port (“Corsa”) of the compiler shipped as @typescript/native-preview@beta with a tsgo entry point. The maintainers are blunt about the goal: keep TS6 semantics, but run the same work with native speed and shared-memory parallelism, usually landing around ~10x faster builds on big codebases. ([devblogs.microsoft.com](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0-beta/))
What matters operationally isn’t the headline; it’s control. TS7 exposes --checkers (default 4), --builders (parallel project-reference builds), and --singleThreaded to force determinism / low-resource mode. Translation: you can finally tune compile latency vs RSS instead of praying your runner doesn’t get OOM-killed mid-build. ([devblogs.microsoft.com](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0-beta/))
Hot-path data structure work: fewer Go maps where it hurts
PR #4296 swaps the old map-backed link side-tables for linear-probing integer hash tables for Node/Symbol links. That’s not a vanity refactor; it’s paying down architectural debt where the checker does millions of lookups and Go map overhead becomes tax you can’t optimize away with flags. Expect this class of changes to keep landing as they sand down bottlenecks that only show up when the compiler is fast enough for the next bottleneck to matter. ([github.com](https://github.com/microsoft/typescript-go/pull/4296))
Crash-class correctness: control-flow analysis stack overflow fix
PR #4274 fixes an ugly CFA edge case: a for-loop initializer that makes flow unreachable could create a cyclic flow graph with no exit, sending reachability analysis into infinite recursion and eventually a stack overflow. That’s the kind of bug that shows up as “compiler randomly died” in CI logs at 2 AM, and it’s exactly the surface area a new foundation needs to harden before GA. ([github.com](https://github.com/microsoft/typescript-go/pull/4274))
Incremental/watch cache invalidation: package.json finally counts
PR #4301 persists package.json locations into tsbuildinfo and folds them into up-to-date checks, so --build / watch workflows rebuild when dependency metadata changes. Cache invalidation isn’t “hard” in the abstract; it’s hard because you ship missing edges like this and engineers learn to distrust incremental builds. This is one of those unsexy fixes that saves real money. ([github.com](https://github.com/microsoft/typescript-go/pull/4301))
The gotchas: JS/JSDoc and the death of Closure-era magic
If you run TypeScript against .js with JSDoc, read the CHANGES doc before you flip anything in production. Corsa intentionally trims legacy JS features (especially Closure-style constructs) and drops special-casing for patterns like constructor-function expandos. Also: .d.ts emit from .js is not promised to match the old compiler; it’s explicitly a non-goal. If your build chain relies on specific declaration output from JS sources, you’re in the blast radius. ([github.com](https://github.com/microsoft/typescript-go/blob/main/CHANGES.md))
TypeScript didn’t get slow because the team forgot how to write code. The JS implementation accumulated a decade of compatibility hacks, and Node’s runtime model is a lousy place to build a CPU-bound compiler that wants predictable parallel throughput. The Go port is a debt payment: same semantics, but a runtime and memory model that lets them scale across cores without pretending everything is async I/O.
Competitors and adjacent tooling have been eating TS’s lunch on raw throughput for years (fast parsers, fast bundlers, partial type systems). The maintainers’ move here is pragmatic: preserve the ecosystem contract first, then take the performance win that native + shared memory makes possible. The beta’s existence is also a warning to tool authors: stop spelunking private compiler internals unless you enjoy living on an unsupported ABI. ([devblogs.microsoft.com](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0-beta/))
Install (beta) and run side-by-side:
npm install -D @typescript/native-preview@beta
npx tsgo --version
npx tsgo -p tsconfig.json
Keep TS6 around for tooling that imports the compiler API (npm alias approach from the maintainers): ([devblogs.microsoft.com](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0-beta/))
npm install -D typescript@npm:@typescript/typescript6
Parallelism tuning (start conservative on CI): ([devblogs.microsoft.com](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0-beta/))
# fewer cores / less RAM
npx tsgo -p tsconfig.json --checkers 2 --builders 1
# debugging / determinism / external orchestration
npx tsgo -p tsconfig.json --singleThreaded
Red Flags (grep your logs; don’t hand-wave these):
- RSS creep or OOM-kills after increasing
--checkers(parallelism isn’t free; it’s memory pressure). - Changed diagnostics in
.js+JSDoc projects; especially anything relying on Closure-era idioms or expando constructor patterns. ([github.com](https://github.com/microsoft/typescript-go/blob/main/CHANGES.md)) - Tooling failures where something imports
typescriptinternals; maintainers explicitly warn the stable programmatic API won’t land until at least 7.1. ([devblogs.microsoft.com](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0-beta/)) - Incremental/watch weirdness around dependency updates; validate that your build actually invalidates on
node_modules/**/package.jsonchurn (PR #4301 is aimed at exactly that class of bug). ([github.com](https://github.com/microsoft/typescript-go/pull/4301))
🛠️ Try These Free Tools
Paste your dependency file to check for end-of-life packages.
Paste your workflow YAML to audit action versions and pinning.
Paste a PEM certificate to check expiry and get a security grade.
Track These Releases