# I'm porting tsc to Go


# I’m porting tsc to Go

I’m porting the TypeScript Type Checker `tsc` to Go, and not Rust. As the creator of [SWC](https://swc.rs/), an extensible Rust platform, this might sound strange. Let me explain.

## Why port `tsc`?

As TypeScript continues to rise in adoption, large projects are facing a dilemma: **type checking is one of the slowest parts of their workflow**. Developers want type safety without the tradeoff of slower iteration cycles.

The TypeScript Compiler, or `tsc`, checks the validity of your types and compiles your code to JavaScript. The more code you have, the longer it takes to compile. On medium-to-large-sized TypeScript projects, this compilation is *extremely slow*. While developers can replace the *transpilation* part of their workflow with SWC, type checking has still been a bottleneck.

## What is a type checker?

A type checker validates your program before execution and ensures you've used correct values for function calls and variable assignments. To prevent you from specifying types everywhere, it also infers variable types whenever possible. Type checking helps you develop with confidence, prevent mistakes, and enables smoother refactoring of large codebases.

## Why not Rust?

I tried to rewrite `tsc` in Rust. It started as a side project and was a lot of fun. I started recreating the type checking logic without looking at the `tsc` source code. 

Early tests of my Rust rewrite showed **62x faster type checking than `tsc`**. To measure the compile-time between SWC and `tsc`, I used the `conformance` test suite from the official TypeScript compiler. Here were the results (using 8 threads):

- `tsc`: 133.2 seconds
- Rust rewrite: **2.13 seconds** **(62x faster)**

Eventually, I realized that rewriting a massive project such as `tsc` would be extremely difficult to continue. But the performance gains were exciting. This led me to try another route: porting instead of a complete rewrite. So, I started looking at the TypeScript source code.

`tsc` uses a lot of shared mutability and many parts depend on [garbage collection](https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)). Even though I’m an advocate and believer in Rust, it doesn’t feel like the right tool for the job here. Using Rust required me to use [unsafe](https://doc.rust-lang.org/std/keyword.unsafe.html) too much for this specific project.

`tsc` depends on shared mutability and has a cyclical mutable reference. Rust is designed to *prevent* this behavior. Having two references to the same data (shared mutability) is undefined behavior in Rust.

Your language choice should be determined by the task, and not by preference. So even though I love Rust, I started experimenting with Go and Zig for this project and chose to use Go.

## Will it be open-source?

Vercel is sponsoring and funding the work to port `tsc` to Go. We’re planning to open-source this work in the future. I’ll also be creating a bridge to use this new version of `tsc` with SWC.

With type checking support, SWC is working to improve the performance of your entire JavaScript / TypeScript toolchain:

- ✅ Transpilation (replacing Babel)
- 🚧 Type Checking (replacing `tsc`)
- 🚧 Minification (replacing Terser)
- 🚧 Bundling (replacing webpack)

For project updates, [follow me on Twitter](https://twitter.com/kdy1dev).

