Industry AnalysisProgramming LanguagesPerformance

TypeScript 10x Faster: Why Microsoft Chose Go Over Rust for Compiler Rewrite

Microsoft’s TypeScript 7.0 compiler, rewritten in Go, achieves 10x performance gains according to the December 2, 2025 progress update—compiling VSCode’s 1.5 million lines in 8.74 seconds instead of 89 seconds. The controversial language choice sparked intense debate across developer communities. Rust, crowned the “most loved language” for nine consecutive years with an 83% admiration rate, seemed like the obvious choice for a performance-critical compiler rewrite. But Anders Hejlsberg, TypeScript’s lead architect, chose Go for a pragmatic reason: Rust’s borrow checker would have required dismantling TypeScript’s cyclic Abstract Syntax Tree structures, turning a one-year port into a multi-year rewrite.

Go delivered 10x gains in a year. Rust’s hypothetical 20x gains would have taken three years. For the 38.5% of developers using TypeScript—2.6 million GitHub contributors, 60 million npm downloads per week—this decision reveals critical lessons about when to prioritize pragmatism over purity in performance infrastructure.

Why Rust’s Borrow Checker Broke the Deal

Microsoft rejected Rust for the TypeScript compiler rewrite because Rust’s borrow checker is fundamentally incompatible with TypeScript’s cyclic Abstract Syntax Tree data structures. Compilers work with recursive, interconnected data where AST nodes reference parents, children, and siblings in complex webs. Rust’s ownership model prohibits circular references unless you use workarounds like reference-counted pointers, which introduces runtime overhead and defeats the performance purpose.

Anders Hejlsberg explained the decision directly: “C# was a top contender for the port, as was Rust. But both would have been a rewrite more than a port. We picked Go because it was the path of least resistance to 10x for *this* particular code base.” The team emphasized that Rust’s borrow checker would require “unraveling cyclic data structures”—an insurmountable task turning a port into complete architectural redesign. When your data structures are inherently cyclic, automatic garbage collection isn’t a flaw. It’s a requirement.

This reveals a constraint rarely discussed in Rust evangelism: Rust’s memory safety guarantees come with structural limitations. For greenfield projects, design around the borrow checker from day one. But for porting existing codebases with cyclic data structures, Rust forces a complete rewrite. Go’s garbage collection, often criticized as a “performance tax,” became the enabling feature that allowed Microsoft to port TypeScript’s architecture intact.

The 10x Performance Proof: Real Benchmark Numbers

The December 2025 progress update provides concrete evidence. VSCode (1.5M lines) compiles in 8.74s instead of 89.11s—10.2x faster. Sentry compiles in 16.25s instead of 133.08s (8.19x faster). TypeORM achieves 9.88x speedup, Playwright 10.1x, and date-fns 9.5x. These aren’t theoretical performance claims. They’re production-ready numbers from Microsoft’s testing on real-world codebases.

Editor performance improved even more dramatically. Language service startup dropped from 9.6 seconds to 1.2 seconds (8x faster). Memory usage fell by approximately 50%. Type-checking compatibility reached 99.63%—of 20,000 test cases, only 74 produce different results, mostly from incomplete features or intentional improvements.

For developers working on large TypeScript projects, this translates directly to faster CI/CD pipelines, more responsive editors, and lower cloud compute costs. The performance pattern also validates Go’s viability for compiler workloads—comparable to Rust’s gains (SWC is 20x faster than Babel) when measured against JavaScript baselines.

Go’s Structural Alignment: The Hidden Advantage

Go won not just for garbage collection, but for structural similarity to JavaScript that made porting straightforward. TypeScript’s compiler is written in TypeScript—a garbage-collected, dynamically-typed language. Go provides garbage collection, structural typing, and concurrency patterns that align with JavaScript’s design. Hejlsberg described Go as “the lowest level language we can get to and still have automatic garbage collection.”

This alignment allowed Microsoft to complete 80% of the compiler port in just six months (August 2024 to February 2025). Circular AST references, recursive data structures, and shared-memory access patterns transferred directly from JavaScript to Go. The team achieved “extreme compatibility”—99.63% test case parity—precisely because Go allowed them to preserve TypeScript’s existing architecture.

Rust would have required flattening ASTs into indexed arrays, using reference-counted wrappers that add runtime overhead, or redesigning the entire compiler architecture. The community questioned the Go choice, but Microsoft’s response emphasized “path of least resistance to 10x.” When porting existing codebases, architectural alignment matters more than raw performance potential.

This challenges the narrative that Rust is always the best choice for performance rewrites. Go’s 10x gains in one year beat Rust’s hypothetical 15-20x gains in three years. For engineering teams evaluating similar rewrites: prioritize compatibility with existing architecture before pursuing theoretical performance maximums.

What TypeScript Developers Need to Know

TypeScript 7.0 targets Q1 2026 release (stable), with TypeScript 6.0 as the final JavaScript-based version. As of December 2025, the native compiler is production-ready for everyday editor use and CLI builds, though some features remain incomplete. Decorators aren’t supported. JavaScript emit only works for ES2021+ targets—no downlevel compilation to ES5 or ES2015. Watch mode exists but isn’t optimized yet.

Developers can test now:

# Install native TypeScript compiler preview
npm install @typescript/native-preview

# Use tsgo instead of tsc
tsgo --project ./tsconfig.json

Microsoft recommends running both tsc and tsgo in parallel during transition to catch edge cases. The migration tool @andrewbranch/ts5to6 handles tsconfig.json updates automatically. Third-party tooling like ts-morph and ttypescript won’t work until the Corsa API stabilizes post-7.0 release.

Major benefits appear immediately for large codebases exceeding 500K lines of code and editor performance on complex projects. Risks include breaking changes for decorator-heavy code (Angular-style) and legacy browser support if targeting ES5. Teams should plan for Q1 2026 adoption, testing with preview builds in late 2025.

Lessons for Language Choice in Performance-Critical Infrastructure

The TypeScript compiler rewrite reveals three critical lessons. First, garbage collection can be an enabling feature, not just a performance tax, when data structures are inherently cyclic. Second, architectural alignment—porting ease—can outweigh raw performance potential when time-to-value matters. Third, pragmatic wins (10x in one year) beat theoretical wins (20x in three years) for business ROI.

This contrasts with the broader JavaScript tooling trend toward Rust—SWC, Deno, Rspack all chose Rust for greenfield development. ESBuild, a Go-based bundler, chose Go for similar reasons as TypeScript: garbage collection, goroutine concurrency, and easier porting from JavaScript tooling patterns. Both ESBuild and SWC deliver similar “order of magnitude” improvements over JavaScript baselines (Webpack, Babel). The pattern emerges clearly: Go for ports, Rust for rewrites.

For CTOs and engineering leaders evaluating similar infrastructure rewrites, the TypeScript case study provides a decision framework. If you’re porting an existing codebase with complex data structures, prioritize architectural alignment—Go makes sense. If you’re building greenfield infrastructure with deterministic performance requirements, Rust’s memory safety may justify the extra effort. The debate isn’t “Go versus Rust” universally. It’s “Go versus Rust for this specific problem with these specific constraints.”

Rust’s “most loved” status doesn’t translate to “best for every problem.” Microsoft prioritized shipping over purity, and developers win—10x faster builds starting Q1 2026, with minimal migration risk thanks to extreme backward compatibility. Sometimes the less fashionable choice is the right engineering decision.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to simplify complex tech concepts, breaking them down into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *