TypeScript 7 shipped — and it's not an ordinary minor. Microsoft has ported the TypeScript compiler and language services from TypeScript to a new native implementation in Go, targeting ~10× faster type-checking. A Next.js preview that can use it landed at the same time.
So I did the obvious thing: asked Claude to measure it on my own codebase. Not a
synthetic benchmark — the real www-site (Next.js, ~4,200 files), before and
after, on the same machine.
This post is in two parts. Part one is the numbers — what the Go compiler actually bought us. Part two is how we measured — the exact prompts from the session, so you can do the same.
Part 1 — The numbers
Short version: type-checking got ~10× faster, and because type-check is the
heaviest phase in our next build, the whole production build dropped from
116 seconds to 72 — without changing a single line of runtime code.
The detail behind the bars:
- Pure compiler (
tsc --noEmit, cold): total time ~31.5s → ~3.0s (~10.5×); the check phase alone 26s → 2.2s (~11.6×). - Type-check inside the build (
next build, the "Finished TypeScript in …" line): 33.7s → 4.0s (8.4×). - Full
npm run buildwall clock: 116.4s → 71.6s — −44.8s, ~38% faster. The compile phase (~36s) and static generation (~5s) didn't move; the whole delta is type-check collapsing.
One thing I didn't expect
The Go compiler shipped a newer lib.dom.d.ts, and it caught three genuine
type errors that TypeScript 5.8 had silently accepted — Node's Buffer /
Uint8Array are no longer implicitly assignable to the web types BodyInit /
BufferSource. Three real sites in production code (two route handlers and a
PWA component). All fixed, and worth landing regardless of the TS7 decision.
Faster and stricter. That's a rare combination.
What about the load test?
The original idea was a before/after load test. I deliberately didn't run
it — the result is a foregone conclusion: it would show zero difference. Our
tsconfig.json sets noEmit: true, so tsc produces no JavaScript at all;
Next.js transpiles with SWC/Turbopack, which is entirely independent of tsc.
The shipped bundles are byte-for-byte identical whether TS5 or TS7 did the
checking. TS7's win is 100% developer and CI throughput: type-check,
next build, editor responsiveness, pre-commit and CI gates. Not runtime.
That's the honest headline: TypeScript 7 makes the build fast, not the app. But when type-check drops from 34 to 4 seconds on every CI run and every commit, you feel it every day.
The recipe (short version)
It's still preview software — wait for a stable Next 16.3 before you lean on it in CI — but it works today:
typescript@7.0.2(the native Gotsc)next@16.3.0-preview.6experimental.useTypeScriptCli: trueinnext.config.ts(PR vercel/next.js#95639 — TS7 dropped the JS API, so Next callstscas a CLI)
One gotcha: a version-pinned patch-package patch on Next has to be moved aside
or regenerated for the preview version, or postinstall fails.
Part 2 — How we measured
The interesting part isn't only the numbers — it's how little it took to produce them. The whole spike was two prompts.
The first one set the frame: worktree, isolated, validate first that the app even builds under TS7, measure after.
Two things in that prompt matter. First: "in a worktree" — the spike runs in
an isolated git worktree, so neither the version bumps nor the moved patch
touch my real checkout. Second: "First step would be to validate" — an
explicit gate. Not "build a benchmark," but "prove it works, then measure." That
gate is why the numbers are trustworthy: the measurement ran serially on an
otherwise idle machine (upgrade → measure → downgrade → measure in the same
worktree), never in parallel — parallel arms would have corrupted the timings.
Once validation was green and the numbers were stable, the second prompt came — the one asking for exactly this post:
That's the whole lineage. The prompt you just read is why Part 1 opens with a
graph, and why Part 2 quotes itself verbatim — including supprot, diffrence
and implmentation. The texture is the point; I don't clean it up.
The method, concretely
No magic — just the discipline of measuring the same thing twice. From
src/apps/www-site:
# Baseline (TypeScript 5.8, JS compiler)
npm ci
npx tsc --noEmit --extendedDiagnostics # ~32s total, ~26s check
# → TypeScript 7 (native Go compiler)
# next.config.ts: experimental.useTypeScriptCli: true
# move the version-pinned patch aside so patch-package won't fail:
mv patches/next+16.2.10.patch /tmp/
npm install -D typescript@7.0.2
npm install next@16.3.0-preview.6
# fix the 3 Buffer→Uint8Array type errors TS7 catches
npx tsc --noEmit --extendedDiagnostics # ~3s total, exit 0
rm -rf .next && npm run build # "Finished TypeScript in ~4s", ~72s total
--extendedDiagnostics is the key: it prints "Total time" and "Check time"
straight from the compiler, so I'm not guessing from wall clock. And because
tsconfig.json sets incremental: true, *.tsbuildinfo has to be deleted
before every cold run — otherwise you're measuring a cache, not a compiler.
Takeaway
The TypeScript team promised ~10×. On a real production Next.js app with ~4,200 files, the native Go compiler delivered ~10.5× on type-check and cut 38% off the whole production build — and caught three bugs on the way. The price: preview software and a single patch gotcha.
And the entire investigation was two prompts and a worktree. Maybe that's the real point: the expensive part of a question like this used to be the work of answering it. Now it's just asking precisely.
