Microsoft spent most of 2025 explaining why the native TypeScript compiler would be written in Go and not Rust. TypeScript 7.0 (tsgo) shipped on July 8, 2026. On October 20, Cloudflare published tsrs, a port of TypeScript to Rust, and says it is "up to 8x faster" than TypeScript 7.0 with "~70% less memory". The fairest comparison in the published numbers puts it closer to 3x.
So we now have two native TypeScript compilers, and only one of them is tsc. I've read the Cloudflare post, the tsrs repo and its benchmark file, Microsoft's announcements and the 207-comment Hacker News thread. My view after all that: both companies picked the right language for their own problem, your CI gate should stay on tsgo, and the thing that worries me is tsrs turning into a second tsc.
What tsrs actually is
The tsrs repo lives under the Oxc project. It describes itself as a Rust port of the TypeScript 7 type checker, meant as a drop-in replacement for the TypeScript 7 compiler and language server, with "100% conformance" as the goal. A few facts that matter more than the headline number:
- The README credits Max Schwenk with the port, and Owner.com sponsored the initial work. Cloudflare and VoidZero are backing it, and Cloudflare says Theo Browne's tsc-rs will be merged with it into one package.
- It tracks the main branch of microsoft/TypeScript (the benchmarks use a 7.1-dev commit) and is aiming for a stable release against TypeScript 7.1. Releases so far are 0.x: v0.18.0 landed on GitHub on October 19, and npm ships it as
0.18.0-ts7.1.0-dev.20260929. - License is Apache-2.0. The README says it is not affiliated with or endorsed by Microsoft.
- Pull requests are closed. Issues with minimal repros are welcome.
- There's a Wasm build,
@tsrs/wasm, targetingwasm32-wasip1. - Known gaps:
--initand--showConfigaren't supported, and the benchmark file flags at least one real tsrs bug (same error count as tsgo on drizzle-orm, different locations).
Cloudflare's post insists "we are not forking TypeScript". It also says "frontier AI models can now do large-scale ports almost independently in a matter of days" and that it will apply the same process it uses for Vinext, where the Next.js test suite runs against Vinext every night, to keep tsrs in sync with upstream, with an agent reviewing upstream changes each morning and opening tracking issues. That's the whole maintenance plan: agents and a test suite.
Why Microsoft picked Go
Ryan Cavanaugh's "Why Go?" discussion from March 2025 is still the best primary source. The main reasons:
- The new codebase had to stay "as compatible as possible, both in terms of semantics and in terms of code structure", because the team would maintain both codebases for a while.
- "Idiomatic Go strongly resembles the existing coding patterns of the TypeScript codebase."
- Go offers "excellent control of memory layout and allocation", and "the downsides of a GC aren't particularly salient in our codebase."
- The admitted weakness: "Go's in-proc JS interop story is not as good as some of its alternatives."
That plan worked. The TypeScript 7.0 announcement reports VS Code going from 125.7s on TypeScript 6 to 10.6s on TypeScript 7, and 8x to 12x speedups on full builds generally. 7.0 is built to match 6.0's type-checking and command-line behavior, which is exactly what you want from a compiler that so many CI pipelines depend on.
Why Cloudflare picked Rust
Cloudflare's argument for Rust is mostly about Wasm: "When you compile a Go program to Wasm, you have to compile Go's garbage collector along with it." Rust's memory management model "enables straightforward memory interactions between a WebAssembly guest and host." If you want a type checker inside a Worker, inside a browser playground, or inside Oxlint as a library, that is a real difference.
The most important comment in the HN thread comes from Daniel Rosenwasser of the TypeScript team. "We even did our own Rust vibe port", he wrote, and the team suspects "a lot of the speed does not just come down to language choice." Some of what makes TS 7.1 faster "actually comes from optimizations discovered in tsrs": work done more lazily, changed allocation patterns, experiments with struct layouts. Cloudflare's post says the same thing from the other side: some 7.1 optimizations "were upstreamed from tsrs".
So the Go vs Rust argument is mostly a proxy war. Go was the right call for a faithful port by the people who own the language. Rust is the right call if you want to embed the checker somewhere a GC is a liability.
tsrs vs tsgo benchmarks: where 8x becomes 3x
These are the published figures. None of them are mine; each row comes from the source named in it.
| Source | Project | tsgo (TS 7.x) | tsrs |
|---|---|---|---|
| Cloudflare blog, same worker count | general claim | baseline (7.0) | up to 8x faster, ~70% less memory |
| Cloudflare blog | TS 7.1 beta vs 7.0 | up to 2.5x faster | n/a |
| bench/RESULTS.md, defaults, 16 vCPU | vscode | 11.10 s, 7.48 GiB | 0.82 s, 2.10 GiB |
| same | mui-docs | 12.66 s, 7.39 GiB | 0.75 s, 1.60 GiB |
| same, watch mode, 8 vCPU | vscode edit-to-report | ~1.2–1.8 s | ~31–34 ms |
| HN, quoting the blog charts | vscode vs TS 7.1 nightly | 5.28 s | 1.73 s |
The 13.55x vscode result in RESULTS.md runs tsgo at its default 4 checkers and tsrs at 16 threads on a 16-vCPU box, compares against typescript@7.0.2 while tsrs ports a 7.1-dev commit, and uses tsrs's PGO-optimized build. When Cloudflare equalizes worker counts, the claim drops to "up to 8x". When you compare against the 7.1 nightly instead of 7.0, the VS Code gap is about 3x. That's still a big result, and 3x is the number I'd quote.
The watch-mode number is the one I'd actually care about. Edit-to-diagnostic in tens of milliseconds instead of over a second is something you feel in an editor all day. A 12-second CI check becoming 1 second mostly isn't, and commenter pier25 has a point: for most projects tsgo is "already plenty fast."
What breaks in TypeScript 7 and in tsrs
tsgo (TypeScript 7.0) ships without a programmatic API. The announcement says so directly: "it does not ship with an API." typescript-eslint, Volar, Vue, Svelte, Astro and MDX tooling still need 6.0. Microsoft's workaround is @typescript/typescript6, which gives you a tsc6 binary and the old API. A new, different API is expected in 7.1.
tsrs has no stable release, only 0.x builds against a 7.1 dev snapshot. --init and --showConfig aren't supported. The README also warns that tsgo itself can produce diagnostics and traces in a different order depending on parallel parse, resolution and check order, so a naive diff between the two will be noisy even when both are right. tsrs canonicalizes some of that by default; tsgo doesn't. And keeping a port in sync with agents that track upstream is a plan nobody has seen survive a major TypeScript release yet.
What to put in CI today
My recommendation for a real project in October 2026:
# 1. The gate stays official
npm install -D typescript@7
# 2. Keep the 6.0 API for typescript-eslint and friends
npm install -D typescript6@npm:@typescript/typescript6
# 3. Before chasing another compiler, tune the one you have
npx tsc --noEmit --checkers 8
# 4. Try tsrs as a non-blocking job and compare results
pnpm add -D tsrs
pnpm exec tsrs --noEmit --checkerAssignment go --noLazyMembers
The two tsrs flags in step 4 are the ones its README recommends for the closest comparison with tsgo. If the error lists match on your codebase for a few weeks, you have a fast pre-check. Your merge gate should stay on tsc.
Oxlint, Biome, swc: who gets type-aware linting
Oxc wins, obviously. Cloudflare names type-aware lint rules in Oxlint as a use case, and the repo lives under oxc-project. Rust linters have spent years approximating types without a real checker, and an in-process Rust type checker fixes that for whoever gets to link against it.
Neither Biome nor swc is mentioned in the Cloudflare post. If tsrs ends up as a crate with a clean API that Biome, swc, Rolldown and anyone else can depend on, the whole Rust JS toolchain gets real types. If it ends up as "the oxc type checker" with its own CLI, its own LSP and its own subtly different diagnostics, we get the Babel-vs-tsc split all over again, this time at the type level, where differences hurt more.
My take is that tsrs is good news as a library and bad news as a rival tsc. The CLI and LSP are what make it look like a rival. The Wasm build and the embeddable checker are the parts I'd want, and I hope that's where the effort goes.
Did Microsoft get it right with Go, or did Cloudflare just prove Rust was the better call all along? And would you put a community port in your CI gate if it were 3x faster? Tell me why I'm wrong.
Top comments (0)