The TypeScript compiler was rewritten in Go and type checking got 10x faster
tsc was slow because the compiler ran as JavaScript. Why TypeScript 7's Go rewrite is faster, why Go and not Rust, and an honest look at how little it changes for a small project.
#TypeScript #Build #Go #Frontend
My blog's frontend was stuck on TypeScript 4.9. As the project grew, the red squiggles in the editor got sluggish, and there were times when a single type check run felt frustrating. Then I saw that TypeScript 7 had rewritten the whole compiler in Go and become 10 times faster , so I took a closer look, wondering if I should upgrade. In this post I'll go over why the old tsc was slow and why moving to Go made it fast. I'll say up front that this is closer to something I read and summarized than something I went through myself. The reason is at the end. The old compiler was written in itself A surprising number of people don't know this, but until now the TypeScript compiler (tsc) was written in TypeScript . In other words, it was ultimately a program that runs as JavaScript. When a compiler runs as JavaScript, it carries two limits with it. The first is that it's single-threaded . JavaScript basically runs one line at a time. Even with several CPU cores, it only uses one. The second is GC pauses . Garbage collection, which cleans up memory automatically, kicks in every so often and execution stops. Type checking means drawing the type relationships of the entire codebase as a graph and following them endlessly, so it runs straight into both of those limits. That's why it got exponentially slower as projects grew. So they rewrote it in Go. Why did it get faster? TypeScript 7 rewrote the compiler from scratch in Go . There are two reasons it got faster. One is that it's compiled to native code . Go compiles down to machine code. Instead of a runtime interpreting it line by line like JavaScript, it runs as code the CPU consumes directly. The other is that shared-memory parallelism works . Go really does run multiple cores at the same time. That's exactly what JavaScript couldn't do. The type graph can be split into several branches and walked at the same time. The numbers make it clear. In the published benchmark, the VSCode codebase (1.5 million lines) reportedly went from 89 seconds to 8.74 seconds, 10.2 times faster. But why Go and not Rust? Vite went with Rust (my previous post), so I wondered why TypeScript chose Go. The reason is interesting. The old tsc was code with a structure that walks around graphs and leans heavily on GC, and Go's memory model fits that structure well, so it was apparently easy to port almost 1:1 . Had they gone with Rust, the ownership model would have forced them to redesign the structure, and that carried the risk of behaving subtly differently from before. If the goal was to carry the behavior over as is and only raise the speed, Go was the reasonable choice. The new compiler could be tried early as an executable called tsgo , and it was stabilized as the official release (7.0) in early 2026. Companies like Bloomberg, Figma, Google, Slack and Vercel reportedly ran it in production ahead of time. Trying it out is simple It has shipped as a separate package since the preview days, so you can run it alongside an existing project without touching it. It reads the same tsconfig, so you only need to change the command. # install it npm install -D @typescript/native-preview # put tsgo where tsc was and run only the type check npx tsgo --noEmit # in package.json the change looks like this "scripts": { "typecheck": "tsgo --noEmit", "build": "tsgo --noEmit vite build" } If type checking is the only thing tsc does in your build pipeline (which is mostly the case for Vite projects, since esbuild does the transpiling), this one-line swap is all there is to it. That said, a few old options were cleaned up in 7.0. Settings that take target below ES5 and the old module resolution modes reportedly no longer work, so if your tsconfig is old, that's the first thing to check. What breaks when you upgrade from 4.9? The version gap is big (4.9 to 7), so there's a good chance that types which used to slide by loosely will now get flagged. That's because some options had their defaults tightened over the 5.x releases. But this really just exposes holes that had been hiding all along, so once you fix them the code ends up sturdier. You upgrade for the speed and end up getting type safety along with it. For my project it's about 3 seconds becoming 0.3 The 10x number drew me in, but when I asked myself whether tsc being slow had ever actually frustrated me on my own project, the answer was no. This blog's frontend is still on TypeScript 4.9 . Even now, in September 2026, as I revise this post, package.json still says 4.9.3. The whole build takes about 6 seconds, of which type checking is probably a few seconds, and making that 10 times faster wouldn't feel like much. I've never worked on a large codebase, so I don't think I understand what this change really means yet. I've heard stories of type checks taking minutes on codebases with hundreds of thousands of lines, but that's someone else's story, not my experience. So this post is closer to "what I read" than "what I went through". The commands above are also based on the docs, not something I ran on my own project. If I end up working on a big project later, I should rewrite this with real numbers then.