TypeScript Port to Go: Microsoft's Bold Move for a 10x Faster Compiler

March 26, 2025 (1y ago)

Microsoft has announced that TypeScript — which adds static typing capabilities to JavaScript through optional type annotations — is being ported to Go, yielding a 10x performance improvement. Here's what that means and why it matters.

But Why?

TypeScript enables development of large-scale applications while staying compliant with JavaScript. However, since the compiler itself runs on TypeScript (via Node.js), it has some fundamental performance constraints:

These limitations become painfully obvious in large monorepos where a full type-check can take minutes.

What is Porting?

Porting means moving to a different language or environment with the same problem statement. It involves converting an existing application or library to function in a different language or platform while preserving core functionality and behavior.

This is different from a rewrite.

Porting vs. Rewriting

Rewriting constructs a new system from scratch. You address the original problem without being constrained by the existing implementation.

Porting converts existing code to a new language while preserving its structure and functionality as closely as possible.

Why port instead of rewrite?

Building a fresh codebase from scratch takes substantial time. In software engineering, the golden rule is: if it's working, don't touch it. The TypeScript ecosystem has thousands of projects depending on specific compiler behaviors — changing them arbitrarily could silently break dependent systems in unexpected ways.

Porting preserves those guarantees while unlocking the performance of a compiled, native language.

Why Go?

Go was chosen over Rust or C# for three reasons:

1. Structural Compatibility

Go maintains semantic and structural compatibility with the existing TypeScript codebase, enabling both versions to be maintained in parallel during the transition. TypeScript's function-based (rather than class-based) architecture also reduces the number of code modifications needed when translating.

2. Automatic Memory Management

Go includes a built-in garbage collector, which significantly reduces memory management overhead during the porting process. A manual memory model like Rust's would require rewriting large portions of logic, defeating the purpose of porting.

3. Built-in Concurrency

Go offers native concurrency support via goroutines and channels. This directly addresses one of TypeScript's core bottlenecks — single-threaded execution — enabling efficient parallel file processing during type-checking.

// Goroutines make parallelising file checks straightforward
func checkFiles(files []string) {
    var wg sync.WaitGroup
    for _, file := range files {
        wg.Add(1)
        go func(f string) {
            defer wg.Done()
            typeCheck(f)
        }(file)
    }
    wg.Wait()
}

What This Means for Developers

You won't need to change a single line of your TypeScript code. The Go port targets the compiler internals only — your .ts files, tsconfig.json, and tooling stay exactly the same. The only difference you'll notice is that tsc runs dramatically faster.

For large projects, a type-check that currently takes 30 seconds could drop to under 3.

Conclusion

Don't rely on one tool or language to tackle every challenge — diversify your approach for smarter solutions. Microsoft's decision to port TypeScript to Go is a great example of picking the right tool for the right job, even if it means a significant engineering investment.

TypeScript
Go
Microsoft
Compiler
Software Engineering

Author

Shailesh Jadav