Why Go wasn’t the right choice for the TypeScript compiler

When the TypeScript team announced they were rewriting the compiler in Go, it was framed as a pragmatic shift driven by performance. Many applauded the decision, including some of my LogRocket author colleagues in their article, TypeScript is Going Go: Why It’s the Pragmatic Choice. But now, with two months of hands-on experience with the Go-powered compiler, it’s time to reflect on the other side of the story: one that’s less about benchmarks and more about the broader developer ecosystem, tooling disruption, and long-term maintainability.

The speed is real. But is that enough?

Why Go wasn’t the right choice for the TypeScript compiler

Let’s start with the obvious: yes, Go is fast. The new compiler is reportedly up to 10× faster in some scenarios. Developers using large codebases in VS Code are seeing faster feedback loops. CI pipelines are shaving seconds to minutes off their runs. These are measurable, valuable wins.
But performance alone doesn’t make a language choice pragmatic.

TypeScript didn’t evolve in isolation. It was born out of and thrives in an ecosystem deeply tied to JavaScript and its tooling. This ecosystem is full of tools like ts-loader, ts-blank-space, custom linters, and AST transformers that depend on long-stable, accessible JavaScript/TypeScript APIs. These tools now face an uncertain future.

Many internal compiler APIs are being rewritten in Go. Some won’t make the cut at all. While the core TypeScript CLI and language services will continue to function, any project that deeply integrates with the compiler internals will likely break or require costly rewrites.

Type-checking loaders, custom compilers, and advanced plugin systems are suddenly brittle or obsolete.

This is more than technical debt; it’s ecosystem debt.

Rust was harder, but it was a better long-term bet

If performance were the driver, why not choose Rust? Tools like SWC and Deno have shown Rust’s ability to deliver both speed and safety in the JS ecosystem. And unlike Go, Rust is already the default language for many modern TypeScript-adjacent projects.

Yes, Rust has a steeper learning curve and lacks a garbage collector. But these challenges come with a payoff: control, memory safety, and the ability to write highly modular, embeddable components. In contrast, Go’s simplistic type system and opinionated concurrency model make it great for monolithic systems, not language tooling that thrives on extensibility.

In short: Rust is harder to port to, but easier to build on. Go is easier to port to, but harder to innovate on.

Go’s limitations are already showing

Beyond the ecosystem breakage and missed opportunity to embrace Rust, the decision to port TypeScript to Go introduces long-term tradeoffs that are already becoming apparent:

Go’s generics support is still catching up

While Go 1.18 finally introduced generics after years of community requests, its type system remains far less expressive than TypeScript’s.

There’s no concept of higher-kinded types, no type inference as powerful as what TypeScript supports, and constrained interfaces often require verbose boilerplate. For a project that revolves entirely around types — and complex ones at that — this is a fundamental mismatch that could slow down future enhancements or make them harder to implement cleanly.

Weak metaprogramming capabilities

Building compilers and static analyzers typically requires a strong reflection system, AST-level manipulation, and introspective APIs. Rust and even JavaScript offer more usefulness in this space.

Friction for contributors and maintainers

TypeScript has built one of the most active language communities in recent history. Most contributors to the TypeScript compiler understand JavaScript or TypeScript deeply, but Go is an entirely different ecosystem with different idioms, tooling, and mental models.

Moving the core compiler to Go introduces a language barrier, increasing friction for contributors and making onboarding more difficult. This could lead to a smaller pool of maintainers, longer feedback cycles, and fewer community-driven improvements.

The original LogRocket post briefly mentioned this concern: the TypeScript team will now write more Go and less TypeScript. This might sound like a non-issue. After all, the language isn’t changing, right?

But writing the language you build is how many of the best DX decisions are made. It’s how bugs are caught early, friction is felt firsthand, and features are shaped by real use. Moving compiler work away from TypeScript breaks that feedback loop.

Over time, this could widen the gap between how TypeScript is built and how it’s used.

While the Go port brings massive benefits on the CLI side (faster builds, better performance), it comes with long-term maintenance and developer experience risks that the TypeScript team will need to actively mitigate.

Ironically, the very pragmatism that TypeScript was built on is now at risk due to reduced community accessibility.

Compatibility isn’t as “drop-in” as promised

The TypeScript team has stated that the CLI and language server will retain “close compatibility,” but early signs show that’s a moving target. For instance:

  • transpileModule compatibility is uncertain
  • The JavaScript API is being rewritten and may become async, which would break synchronous build tools and transforms
  • Projects like ts-loader likely won’t support type checking mode anymore, a significant loss for webpack users

These are not minor implementation details. They’re breaking changes at the heart of the TypeScript development workflow.

The web dev community wanted Rust

Unsurprisingly, many in the web development world were disappointed that the TypeScript team chose Go over Rust. There’s a large, if not majority, portion of the community that adores Rust, and in some corners, it feels like there’s a push to have everything rewritten in it.

And to be fair, valid concerns and thoughtful arguments are being raised in these discussions.
For example, Evan You, the creator of Vue.js and now involved in Rust-based tooling, publicly voiced concern about Go’s performance in WebAssembly.

His point is critical: web-based editors, playgrounds, and development tools often need to run the TypeScript compiler inside the browser, which effectively means running it as a WASM module:

evan you X post disagreeing with Go decision

If Go-based TypeScript performs poorly in that WASM context, it could significantly limit its usefulness in those browser-contained environments. In fact, in his testing, even simple typechecking tasks in Go-WASM were slower than existing JavaScript-based implementations, a worrying datapoint for those invested in web IDE performance.

So while Go may be the right tool for the server-side CLI and IDE tooling, Rust could’ve had the upper hand in all use cases, including browser-based use cases, if the team had the resources and time to do a full rewrite.

Pragmatism shouldn’t ignore community momentum

TypeScript’s success has always been about more than performance. It’s been about the ecosystem: DefinitelyTyped, tight IDE integration, predictable APIs, and a vibrant community of contributors and tool authors.

The switch to Go may be a pragmatic move in the short term, but it risks alienating the very developers who built the tools that made TypeScript indispensable in the first place.

If pragmatism is the guiding principle, then perhaps we need to zoom out. Is it truly pragmatic to chase performance at the expense of ecosystem continuity, contributor inclusivity, and long-term extensibility?

Conclusion

The Go compiler for TypeScript is a bold move. It brings real speed gains, and those will benefit many developers. But two months in, it’s clear that the costs are deeper than expected. Go, while easy to work with for a small core team, imposes limitations that TypeScript and its ecosystem will feel for years to come.

If the TypeScript team had chosen Rust, the path might have been steeper up front, but the payoff in safety, performance, and ecosystem alignment would have been stronger and more future-proof.

Go was a pragmatic choice if pragmatism only means “easy to build and fast to run.” But TypeScript has always stood for more than that.

Now, the question is whether the community will accept these trade-offs or start building their compilers in Rust anyway.

The post Why Go wasn’t the right choice for the TypeScript compiler appeared first on LogRocket Blog.

 

This post first appeared on Read More