
TypeScript in Go: Why Not Rust?
Published
TypeScript is getting ported to Go !
That’s exciting news since it’ll give us ~10x faster compilation times via tsc
and ~8x faster type checking in IDEs like VS Code. Those numbers might, of course, even improve since the porting is not done yet!
But despite those dramatic improvements, there seems to be one main question (or even criticism): Why not Rust?
Because there are good reasons - reasons that are actually explained pretty well by the TypeScript team.
But since not everyone is willing to go through multiple videos, articles and discussions, I did my best to write up a quick summary and overview here.
Rust Can Deliver Amazing Performance!
When it comes to performance (i.e., runtime performance, execution speed, memory efficiency), Rust is one of the best languages you can choose.
At least, if you’re capable of unlocking that performance. If you’re writing poor or suboptimal Rust code, you will very likely end up with poorly performing applications - or at least you’ll not be able to achieve the best possible performance. That’s true for all programming languages and libraries: If you can’t use them, you very likely don’t get their advantages (or you only get a subset).
But due to its potential performance benefits, along with languages like C or C++, Rust is a popular choice for performance-critical applications. For example, some core Windows libraries are getting re-written in Rust, as it seems .
Since Rust seems to be especially popular in the web development community (or at least in some pretty loud part of it), it seems like an obvious choice for a re-write. At least, that would’ve probably saved the TypeScript team some explanation work and discussions in the short term.
But “rewrite” and “short term” are exactly the problems here…
Oh, and by the way, there are, of course, also valid concerns about Go’s performance .
While I agree Go is the the pragmatic choice for a 1:1 port, my biggest concern is Go’s relatively subpar WASM performance.
As a data point, esbuild’s WASM build performs quite poorly in web containers, even slower than js bundlers like Rollup.
In the screenshot below, looks like a basic hello world type check with tsgo WASM takes more than 1 second.
There are many legitimate use cases where we may need to run tsc in the browser - in-browser IDEs and playgrounds in particular. If tsgo WASM ends up performing poorly, or even worse than current tsc, does it mean we will have to stick to tsc-in-js for such use cases?
Porting vs Re-writing
It’s important to understand that TypeScript being ported to Go is absolutely not the same as it being rewritten in Go (or some other language).
Porting the codebase means that it’s essentially “copy & pasted & adjusted” (kind of). The TypeScript team does not start with a blank, new project and rewrite the language from scratch.
Whilst that would be fun (as they also admit), it would not be feasible - for a couple of reasons:
- Time: Rewriting takes much more time. Despite the experience and learnings the TypeScript developers have, it would take them years to rewrite TypeScript in a new language.
- Stability: TypeScript is extremely popular - it gets used by tens of thousands of projects and libraries. A rewritten version would likely introduce (more or less) subtle changes (or even bugfixes) that will break many of those projects.
- Maintainability: The TypeScript team (and external contributors) are committed to maintaining the TypeScript codebase - both the “old”, JavaScript-based one as well as the new one. That gets much simpler if the codebases are very similar (e.g., in structure).
TypeScript Is In It For The Long-Term
TypeScript is not some new niche project that’s likely to go away in a few months.
It’s been around for years and it’s more popular than ever!
Therefore, stability and maintainability are key! The TypeScript people can’t compromise on those two points.
They also can’t spend (waste?) years on a rewrite that would negatively impact the development of the currently used (JavaScript-based) version. Being able to write the Go-based TypeScript version side-by-side with the currently active JavaScript-based version is crucial.
In a world of endless time, resources, manpower (or an almighty AI), that tradeoff might not be necessary. But we don’t live in that world. And even if we were, the stability argument (i.e., a rewrite potentially breaking existing projects) would still matter.
I don’t know about you, but I’ll take a 10x improvement over a theoretical 20x improvement, which is not achievable, any day.