Jagadhiswaran Devaraj

Mar 12, 2025 • 7 min read

Why TypeScript is Moving to Go and Why It Matters

Microsoft is rewriting TypeScript’s compiler in Go for faster builds, better performance, and a smoother developer experience. Here’s what it means for you.

If you’ve ever worked with TypeScript on a large project, you’ve probably encountered slow build times, memory-hungry processes, and sluggish editor performance. While TypeScript is great for scaling JavaScript applications, its tooling has been struggling to keep up.

Microsoft has now decided to rewrite TypeScript’s tooling (compiler, type checker, and language server) in Go, moving away from its current self-hosted JavaScript/TypeScript implementation running on Node.js.

This shift is a big deal for performance and developer experience. In this article, we’ll cover:

  • Why is TypeScript Moving to Go?

  • How Moving to Go Improves TypeScript’s Performance

  • How Will This Improve Developer Experience?

  • Why Not Rust Instead of Go?

  • The Future of TypeScript with Go


Why is TypeScript Moving to Go?

1. The Performance Limitations of Node.js

Right now, TypeScript’s compiler (tsc) and language server (tsserver) run in Node.js, which has some serious performance bottlenecks:

  • Single-threaded execution → Node.js runs JavaScript, which doesn’t efficiently use multiple CPU cores.

  • High memory usage → The V8 engine and JavaScript’s garbage collection struggle with large-scale type-checking.

  • Slow startup times → Every time TypeScript runs, it has to spin up the Node.js runtime.

For example, If you’ve ever had VS Code slow down while working on a TypeScript project, you’ve seen this in action. The TypeScript Language Server (tsserver) often hogs memory and CPU, and that’s largely because it’s written in JavaScript.

Here’s how TypeScript’s existing tooling currently processes files:

// TypeScript parsing in JavaScript (simplified)
const fs = require("fs");
const ts = require("typescript");

const file = fs.readFileSync("example.ts", "utf-8");
const sourceFile = ts.createSourceFile("example.ts", file, ts.ScriptTarget.ESNext);

console.log(sourceFile.statements);

This is sequential and runs in a single-threaded environment, which is inefficient for large-scale projects.

2. Go’s Performance Advantages

By rewriting TypeScript tooling in Go, Microsoft is solving these issues:

  • It’s compiled → Unlike JavaScript, Go compiles directly to native machine code, so no runtime overhead.

  • It has great concurrency → Go’s goroutines allow multiple tasks (like type checking) to run in parallel.

  • It’s lightweight → Go binaries have fast startup times and low memory usage.

  • It’s easy to work with → Compared to something like C++, Go is simple and has great tooling.

For example, here’s how a Go-based TypeScript parser might process files in parallel:

package main

import (
	"fmt"
	"os"
	"sync"
)

func parseFile(file string, wg *sync.WaitGroup) {
	defer wg.Done()
	content, _ := os.ReadFile(file)
	fmt.Println("Parsed:", file, "Size:", len(content))
}

func main() {
	files := []string{"file1.ts", "file2.ts", "file3.ts"} // Simulated TypeScript files
	var wg sync.WaitGroup

	for _, file := range files {
		wg.Add(1)
		go parseFile(file, &wg) // Running file parsing in parallel
	}

	wg.Wait()
	fmt.Println("All files parsed.")
}

Here, Go efficiently runs multiple file parsing tasks concurrently, something JavaScript can’t do efficiently without worker threads.

3. Go’s Garbage Collection is Better Suited for TypeScript’s Needs

TypeScript needs to process massive amounts of abstract syntax trees (ASTs) to check types, and Go’s garbage collector handles this way better than JavaScript’s V8 engine.

With Go, Microsoft can make TypeScript’s compiler and tooling up to 10x faster.


How Moving to Go Improves TypeScript’s Performance

The shift to Go is expected to have far-reaching performance improvements across multiple aspects of TypeScript development.

1. Faster Type Checking and Compilation

The primary function of TypeScript’s compiler (tsc) is parsing and type-checking thousands of files, which is computationally expensive. Go’s native execution and multi-core processing will allow these tasks to be parallelized, significantly improving:

  • Build times for large projects

  • Incremental compilation speed

  • Performance in continuous integration (CI/CD) pipelines

2. Improved Editor Responsiveness

Currently, the TypeScript Language Server (tsserver) often causes high CPU and memory usage, leading to slow performance in editors like VS Code. With Go, the language server will be able to:

  • Start instantly, reducing delays in autocomplete and type checking

  • Use less memory, making it more responsive in large codebases

  • Handle multiple operations concurrently without blocking UI interactions

This means smoother development workflows and faster feedback loops.

3. Reduced Memory Footprint

One of the biggest drawbacks of the existing TypeScript tooling is its heavy memory consumption. The new Go-based implementation will:

  • Optimize garbage collection for handling large abstract syntax trees (ASTs).

  • Reduce memory leaks, which are common in long-running Node.js processes.

  • Improve efficiency in resource-constrained environments, such as serverless functions and edge computing.

4. More Efficient Tooling for Monorepos

Large-scale monorepos with thousands of TypeScript files often struggle with:

  • Slow dependency graph resolution

  • Long type-checking times

  • High memory usage in CI/CD environments

Go’s parallel processing and efficient memory management will allow TypeScript to scale more effectively in enterprise environments.


How Will This Improve Developer Experience?

1. Faster Type Checking and Compilation

Right now, tsc can be painfully slow on large projects. The new Go-based compiler will:

  • Parallelize type checking, significantly reducing build times.

  • Reduce memory usage, making compilation more efficient.

  • Improve incremental builds, making development workflows smoother.

For example, TypeScript’s existing incremental build system looks something like this in JavaScript:

const ts = require("typescript");

const program = ts.createIncrementalProgram({
    rootNames: ["app.ts"],
    options: { incremental: true },
    configFileParsingDiagnostics: [],
});

In Go, this will be vastly more efficient, using goroutines to handle different parts of the build simultaneously.

2. Improved Editor Performance (VS Code, WebStorm, etc.)

One of the most noticeable improvements will be VS Code’s speed when working with TypeScript. Currently, tsserver can cause high CPU usage, especially in large projects.

A Go-based TypeScript Language Server will:

  • Start instantly, without the overhead of a JavaScript runtime.

  • Provide faster autocomplete and type-checking in editors.

  • Use less memory, preventing slowdowns.

For example, right now, VS Code’s TypeScript server runs something like this:

const server = new TypeScriptLanguageServer();
server.listen(3000);

The new Go-based implementation will be a standalone native binary, making it significantly faster.

3. Lower Memory Usage and Better CI/CD Performance

In CI/CD pipelines, TypeScript build times can be a bottleneck. A Go-based tsc will:

  • Run faster on CI servers (useful for enterprise monorepos).

  • Consume fewer resources, reducing cloud costs.

  • Enable better parallel execution, improving build times.

For example, a Go-based CI process might distribute builds across CPU cores like this:

package main

import (
	"fmt"
	"runtime"
)

func main() {
	cores := runtime.NumCPU()
	fmt.Println("Using", cores, "CPU cores for TypeScript builds")
}

This is not possible in Node.js without using worker threads, which introduce additional complexity.


Why Not Rust Instead of Go?

A common question that arises is why Microsoft chose Go over Rust, given that Rust is often associated with high-performance system-level programming.

1. Development Complexity

Rust offers superior performance due to its manual memory management and zero-cost abstractions, but these benefits come at a cost:

  • Rust has a steep learning curve, making it harder to adopt for teams that need rapid development cycles.

  • Memory safety guarantees require more boilerplate, increasing complexity.

  • Rust’s compiler is much slower compared to Go’s, which would slow down the development process.

For a project like TypeScript’s tooling, ease of development and maintainability are just as important as raw speed.

2. TypeScript’s Workload is Better Suited to Garbage Collection

TypeScript’s compiler works extensively with large temporary data structures, such as ASTs and type resolution caches. A garbage-collected language like Go is well-suited for this workload.

  • Rust’s manual memory management would introduce unnecessary complexity.

  • Go’s garbage collector allows for easier memory handling without sacrificing too much performance.

3. Go is Simpler to Maintain

Go was designed for simplicity, readability, and developer productivity, making it an ideal choice for a project that will be actively maintained by a large team.

  • Go has a smaller, more predictable feature set, which reduces long-term maintenance overhead.

  • Microsoft’s team already has experience with Go, making adoption smoother.

While Rust excels in low-level system programming, Go provides a balance of speed, simplicity, and scalability, making it the better choice for TypeScript’s tooling.


The Future of TypeScript with Go

The transition to Go represents one of the most significant architectural changes in TypeScript’s history. Once complete, this move will:

  • Drastically reduce build times and editor lag.

  • Improve scalability for large TypeScript projects and monorepos.

  • Make TypeScript more efficient in serverless and edge computing environments.

  • Enhance the overall developer experience by providing faster feedback loops.

This shift is not just about performance—it’s about ensuring TypeScript remains the best choice for large-scale JavaScript development in the years to come.


Final thoughts

Microsoft’s decision to rewrite TypeScript’s tooling in Go marks a major shift toward better performance and scalability. The new Go-based tooling will address long-standing pain points like slow builds, high memory usage, and editor sluggishness, making TypeScript faster and more efficient for developers.

While Rust was a potential choice, Go’s simplicity, garbage collection, and concurrency model made it a more practical option. This transition ensures that TypeScript remains the best choice for large-scale JavaScript applications in the coming years.

The future of TypeScript is not just about type safety—it’s about speed, scalability, and efficiency.

Would you like to see any new specific benchmarks or a deep dive into the internal architecture of the new Go-based TypeScript tooling? Let me know!

- Jagadhiswaran Devaraj


📢 Stay Connected & Dive Deep into Tech!

🚀 Follow me for hardcore technical insights on JavaScript, Full-Stack Development, AI, and Scaling Systems:

🐦 X (Twitter): jags

✍️ Read more on Medium: https://medium.com/@jwaran78

💼 Connect with me on LinkedIn: https://www.linkedin.com/in/jagadhiswaran-devaraj/

Let’s geek out over code, architecture, and all things in tech! 💡🔥

Join Jagadhiswaran on Peerlist!

Join amazing folks like Jagadhiswaran and thousands of other people in tech.

Create Profile

Join with Jagadhiswaran’s personal invite link.

0

4

1