cat posts/2025-03-18-a-10x-faster-typescript.md
A 10x faster TypeScript, written in Go
77.8 seconds to 7.5. That’s the headline number in A 10x Faster TypeScript, which Anders Hejlsberg posted last Tuesday: the TypeScript compiler is being ported to native code, in Go, and that’s how long type-checking VS Code’s 1.5 million lines takes before and after. I wrote in January last year about the line from his Turbo Pascal to C#, so I won’t redo it, except to say it’s nice to see him working on compiler speed again.
The other numbers are in the same range. Playwright goes from 11.1 to 1.1. Loading the VS Code project in the editor drops from about 9.6 seconds to 1.2, and memory use is roughly half, before they’ve tried to optimize it. The plan is that the native version becomes TypeScript 7, the current JavaScript codebase carries on as 6.x for a while, and there’s a command-line preview by the middle of the year, with full builds and the language service by the end of it.
The speedup is something like half native code and half parallelism. The current compiler is JavaScript running on one thread. The Go version can check files on several cores at once with shared memory, which JavaScript can’t really do.
Why not C#?
That’s the first question every .NET person I know asked, me included, and it’s all over the GitHub discussion. TypeScript and C# share an author, Microsoft owns both, and C# has had native AOT compilation for a couple of years. It’s hard not to read it as a vote of no confidence.
Having read the team’s answer and watched Hejlsberg’s interviews, I think it isn’t one, and it’s fair. The word they keep using is port, not rewrite. They want the new compiler to behave exactly like the old one, bugs and all, and they’ll be maintaining both side by side for years, so they want a codebase where a fix in one can be carried across to the other almost line for line. The existing compiler is written in a style that’s mostly functions and plain data structures, with very few classes, and idiomatic Go looks a lot like that. Idiomatic C# doesn’t. Hejlsberg also called C# “bytecode-first”, in the sense that native AOT is the newer path and not available everywhere, where Go has always compiled to a native binary on every platform they care about. And they wanted a garbage collector, because the compiler’s data structures are full of cycles and they didn’t want to rethink memory management in a port, which is the usual answer to “why not Rust”.
I’d have liked it to be C#. I spent the MVP years writing it and I still write it at work most weeks. But if I imagine maintaining two copies of a large codebase in parallel, I’d want them to look alike too.
What it changes for us
Our frontend is about 140,000 lines of TypeScript, and the type-check is the slowest step in CI that isn’t a test, a bit over 40 seconds. Locally, the editor takes long enough to settle on a big file that people have learned to start typing before the red squiggles are right, which is a bad habit to train into a team. If both of those really drop by 8–10x, it’s not life-changing, but it moves type-checking from something you wait for to something that’s just there, which is what Turbo Pascal did for me in the first place.
I cloned the typescript-go repo on Saturday and built it, and it checked our frontend in under five seconds, but the README is clear that it’s incomplete and I saw some errors the current compiler doesn’t report, so I’m not treating that as a measurement. I’ll try it properly when the preview ships. The thing I’ll actually watch is the API for tools, because our lint setup and a couple of build plugins call into the compiler from JavaScript, and that’s the part the team says is still being designed.