The real reason Microsoft is rewriting TypeScript in Go
4 takeaways for developers, and how Go is changing everything.
TypeScript (TS) just went all-in and decided to rewrite its compiler in Go, promising up to a 10x performance boost.
If you’ve ever sat watching your terminal chew on tsc for what feels like the runtime of The Lord of the Rings Extended Edition, this is big news.
Go is touted for its efficiency and concurrency capabilities, and this rewrite helps TypeScript overcome the bottlenecks and challenges that otherwise threatened TS's relevance for the future of software development.
We can expect Microsoft to release an initial preview of the Go-based compiler later this year, and have it generally available next year.
In the meantime, I want to discuss what this rewrite means for you today.
I'll cover:
The limitations of the current TS compiler
Why Microsoft chose Go over Rust or C#
What the new Go-based compiler means for large projects
4 key engineering lessons from this rewrite
Let's dive in.
Why the TS compiler needed a redo
The current TypeScript compiler is implemented in TypeScript itself (a form of bootstrapping). It's then transpiled to JavaScript and runs in a JavaScript runtime like Node.js.
Here’s how the current architecture looks:
So what’s the problem with this compiler?
It has several limitations:
Node.js runs JavaScript in a single thread, which quickly hits CPU limits for CPU-bound tasks like type-checking.
JavaScript’s memory model and garbage collector struggle with massive, cyclic type graphs, causing slowdowns and unpredictable pauses.
JavaScript runtime adds inherent overhead — even with JIT, it can’t match the raw performance of a compiled, natively optimized binary.
As codebases scale (hello monorepos), you end up with sluggish CI/CD pipelines and IDEs that feel like they’re running on a potato.
These issues didn't impact small projects so much. But at scale, they were deal-breakers. To survive, TypeScript's only real solution was a full compiler rewrite.
Enter: the Go-based compiler
Microsoft evaluated multiple languages, including Rust and C#, before landing on Go.
Here’s why Go won:
Structural compatibility: Go's type system and memory model align well with TypeScript's internal data structures, particularly for cyclic graphs. This enables a more straightforward 1:1 port of the algorithms, reducing risk and simplifying maintenance.
Efficient memory management: Go's garbage collector offers a good balance of performance and simplicity for managing the lifecycle of the numerous objects created during type checking, without requiring manual memory management.
Concurrency advantages: Type checking involves traversing syntax trees and performing polymorphic type checks—operations that benefit significantly from Go's built-in concurrency primitives.
Familiar patterns: Go's programming patterns are reasonably similar to TypeScript's original codebase, easing the transition for the development team and ongoing maintenance.
API design opportunities: The transition to Go allows for more deliberate API design, improving long-term flexibility without breaking compatibility.
The result? A complete architecture rewrite:
The new Go-based compiler will enable TypeScript with:
Native, compiled binary: Go compiles to optimized native executables for each target OS (Linux, Windows, macOS), eliminating runtime overhead
Parallelized compilation: Go's goroutines and channels enable the compiler to parallelize type-checking tasks across available CPU cores
Efficient memory management: Go's garbage collector is better suited to the memory patterns of a compiler, offering more predictable performance
Behavior preservation: Despite the rewrite, the compiler will maintain the same behavior and compatibility with existing TypeScript code
This is TS’s "Python GIL" moment. Just like Python’s Global Interpreter Lock became a concurrency dead-end and spawned migrations to Go and Rust for certain workloads, TypeScript’s single-threaded, JS-bound compiler hit its wall. The rewrite is Microsoft’s acknowledgment that developer tooling needs to scale in lockstep with our ever-growing codebases.
Impact on development
For large codebases and monorepos, the new TS compiler will bring a lot to the table:
Reduced build times: What took minutes could now finish in seconds.
More responsive developer tools: IDE features like type-checking and autocomplete will feel snappier.
Faster CI/CD: Pipelines spend less time waiting for compilation.
The benchmarks speak for themselves in the figure below:
The Go-based compiler leaves the original compiler in the dust as far as compilation times go.
That said, the Go-based gains go beyond speed, including:
Faster feedback loops
Quicker automated refactoring
AI-assisted tooling (code review, analysis) running without bottlenecks
Here’s how Go’s technical strengths cascade into your daily developer experience:
The new compiler's reduced latency makes real-time code analysis and large-scale static analysis feasible. In the same way that just-in-time (JIT) compilers unlocked performance for Java and JavaScript ecosystems, this Go-based compiler will unlock performance for AI tooling for years to come.
4 Engineering Takeaways from the TypeScript-Go Rewrite
This rewrite is a case study in making tough architectural calls. What can engineers learn from it?
Concurrency isn’t optional at scale: If your tooling or system processes huge datasets (in this case, large type graphs), single-threaded architectures will eventually betray you.
Sometimes, you can’t optimize your way out — you have to rewrite: Refactoring helps, but fundamental architectural ceilings require bold changes.
Language choice matters: The right tool for the job is not a meme. For compiler construction, Go’s concurrency and memory model beat out Rust’s complexity and C#’s ecosystem lock-in.
Technical debt includes architectural debt: Even successful, widely used projects will eventually hit architectural limits. Don’t wait for developer pain to reach crisis levels before acting.
This compiler rewrite should have an immediate impact on development workflows (for the better).
And if you're working with TypeScript, just know that:
Your TypeScript code can stay exactly the same.
The Go-based compiler will still run in the browser with WASM.
The speed of type-checking and compilation will improve, but your compiled JS runtime performance stays the same.
But beyond this is an even bigger story: Go is quietly becoming the go-to language for performance-critical developer tools.
Stay tuned for next week, where I'll break down why Go is becoming the backbone of modern software development (and why you should learn it).
And if learning Go is already on your radar, you can start writing Go and reaping its benefits in Educative’s comprehensive course: The Way to Go.
Happy learning!