TypeScriptのコンパイラをGoに移植｜10倍高速になった tsgo とは

# はじめに
2025年3月12日、MicrosoftはTypeScriptのコンパイラをGo言語に移植する「***Project Corsa***」を発表し、最近注目を集めていますね。
この発表は個人的にも、こうした流れによって再びGoが注目を浴びていることが嬉しく、本記事を書くきっかけになりました。

TypeScriptはJavaScriptに型の概念を導入した言語ですが、既存のコンパイラはTypeScript自体で実装されており、大規模プロジェクトでは処理速度やメモリ消費といった課題が指摘されていました。

この問題を解決するため、Microsoftは **TypeScriptのコンパイラをGoでネイティブ実装する計画** を進めています。  
この新しいコンパイラは「`tsgo`」と呼ばれ、現在の `tsc` よりも **最大10倍高速** になると発表されています。

本記事では、なぜGoが選ばれたのか、どのようにして高速化が実現されたのかについて整理していきます。

#  なぜTypeScriptコンパイラをGoに移植するのか？

## TypeScriptのパフォーマンス課題
TypeScriptは、JavaScriptの型システムを強化し、コードの品質を向上させるために開発されました。
しかし、現在のTypeScriptコンパイラ（`tsc`）はJavaScriptで実装されており、Node.js環境で動作するため、以下のようなパフォーマンス上の課題を抱えています。

### 1. *計算負荷の高い処理に不向き*
- `tsc`はシングルスレッドで動作するため、大量のコードを解析・型チェックする際に並列処理を活用できない
- CPU負荷が高くなると処理が詰まりやすい（特にCI/CD環境でのビルド時間に影響）

### 2. *メモリ消費の増大*
- `型チェック`や`AST`（Abstract Syntax Tree)[^1]の構築がメモリを大量に消費し、大規模プロジェクトではメモリ不足を引き起こしやすい
- `GC`(ガベージコレクション)の影響で、特定の処理が一時的に遅くなることがある
 
### 3. *ビルド時間の長さが開発者体験（DX）を阻害*
- コンパイル時間が長くなると、ホットリロードや開発のフィードバックループが遅くなる
- CI/CDパイプラインでのビルド時間が増大し、大規模チームでの開発効率が低下
### 4. *JavaScriptはコンパイラ用途には向いていない*
- `JIT`（Just-In-Time）コンパイルのオーバーヘッドがあり、ネイティブコードに比べて速度面で不利
- 低レイヤーの最適化が難しく、最適化の余地が限られている

まとめると以下の4点！

:::note
**💡 ポイント**
- **並列処理ができず、計算負荷の高い処理に不向き**（Node.jsはシングルスレッドのため並列処理が苦手）
- **メモリ使用量が増加し、大規模プロジェクトでパフォーマンスが低下**
- **ビルド時間が長く、開発のフィードバックループが遅くなる**
- **JavaScriptの特性上、低レイヤーな最適化が難しく、パフォーマンスの限界がある**
:::

これらの問題を解決するために、**コンパイラをGo言語で実装し、ネイティブバイナリ化することで、劇的な高速化を実現することが狙い**です。

## なぜGo言語なのか？
TypeScriptコンパイラの移植先として、C#やRustではなく**Go言語**が選ばれた理由について、TypeScriptのリードアーキテクトである[*アンダース・ヘルスバーグ氏*](https://devblogs.microsoft.com/typescript/typescript-native-port/) 、そして、[*Why Go?*](https://github.com/microsoft/typescript-go/discussions/411) では以下の点を挙げています。

### 1. *既存のJavaScript版コードベースと互換性が高い*
- TypeScriptコンパイラの移植は **「書き換え」ではなく「移植」** として行われる
- `Go` は TypeScriptの既存コード構造と類似しており、移植が容易
- `Rust`や`C++` ではメモリ管理の方式が異なるため、大幅なコード変更が必要になり、両コードベースの維持が難しくなる
- `Go`ならばコード変更の移植がスムーズに行え、JS版と並行して開発を続けられる

### 2. *ネイティブバイナリを生成できる*
- `Go`はクロスプラットフォームに対応したネイティブバイナリを簡単に生成できる
- JavaScript（`tsc`）はNode.js環境で動作するが、`Go` であればNode.jsに依存せずに動作でき、**起動時間や実行速度の最適化が可能**
- これにより、**コンパイル速度やエディター補完のレスポンスが向上**

### 3. *データレイアウトの細かい制御が可能*
- `型チェック`や`AST`（Abstract Syntax Tree)[^1]の解析など、コンパイラ処理では**データ構造の最適化が重要**
- `Go`はC言語に近いデータレイアウトの制御が可能であり、メモリの割り当てを効率化できる
- 特に、**TypeScriptの型システムは複雑であるため、効率的なメモリ管理が求められる**

### 4. *ガベージコレクション（GC）の最適化*
- Rustと異なり、`Go` は**GC（ガベージコレクション）** を備えており、手動のメモリ管理が不要
- **コンパイラ開発では、大量のメモリ管理が必要**になるため、GCの存在は開発者の負担を軽減する
- 一方で、`Go` のGCは高性能で**リアルタイム処理にも適しており、コンパイル時のパフォーマンス低下が抑えられる**
- バッチ処理ではプロセス終了時にGCを実行できるため、**オーバーヘッドがほぼゼロ**
- 言語サーバー（LSP）[^2]環境でも、GCの適切なタイミングを制御できるため、メモリ管理の負担が少ない

### 5. *グラフ処理（ASTトラバース）に適した設計*
- TypeScriptのコンパイラは、`AST`（Abstract Syntax Tree)[^1]の上下移動（`upward & downward walks`）を多用
- `Go`はこのようなグラフ処理をシンプルに実装でき、**JavaScript版の構造に近い形で移植可能**
- これにより、既存の最適化ロジックをGoでも維持しやすくなる

### 6. *並列処理（`Goroutine`）による高速化*
- TypeScriptのコンパイラは、大量のコードを並列に解析・コンパイルする必要がある
- `Go`の **Goroutine** を活用することで、並列処理が容易になり、コンパイル速度が大幅に向上
- Node.js（**シングルスレッド**）では難しかった並列処理が、`Go移植`によって可能になった

### 7. *JavaScriptとの相互運用の課題と今後の対応*
- JavaScript版の`tsc`は、APIを自由に変更できる仕様になっており、パフォーマンス最適化が難しい
- Go版では、より意図的なAPI設計に移行する予定
- インプロセスでのJS連携はRustや他の言語より弱いが、今後の改善を予定
- **最適なAPI設計を行うことで、エコシステム全体のパフォーマンス向上につながる可能性がある**

TypeScriptコンパイラの**Go移植**は、ゼロからの再実装ではなく「***移植***」であることが大きなポイントです。

もし完全に新しいTypeScriptコンパイラを開発するなら、Rustのような低レイヤーな制御が可能な言語が選ばれた可能性も高いでしょう。
しかし、今回の「**Project Corsa**」はあくまで既存のTypeScriptコンパイラの構造を維持したまま、より高速なGo実装に置き換えることを目的としています。

そのため、「**移植だからこそGoが選ばれた**」 というのが本質的な理由だと思います。

# どれくらい早くなったのか？
最初の方にも述べた通り、Go実装のTypeScriptコンパイラ（`tsgo`）は、既存のTypeScriptコンパイラ（`tsc`）と比較して、**最大10倍以上の処理速度向上**を実現できるとのことです。

## ベンチマークの結果
[**A 10x Faster TypeScript**](https://devblogs.microsoft.com/typescript/typescript-native-port/) というオフィシャルの記事で様々なコードベースに対するコンパイル時間の比較があったのでそちらを引用します。

| **Codebase** | **Size (LOC)** | **Current (tsc)** | **Native (tsgo)** | **Speedup** |
|-------------|--------------|----------------|----------------|------------|
| [**VS Code**](https://github.com/microsoft/vscode) | 1,505,000 | 77.8s | 7.5s | **10.4x** |
| [**Playwright**](https://github.com/microsoft/playwright) | 356,000 | 11.1s | 1.1s | **10.1x** |
| [**TypeORM**](https://github.com/typeorm/typeorm) | 270,000 | 17.5s | 1.3s | **13.5x** |
| [**date-fns**](https://github.com/date-fns/date-fns) | 104,000 | 6.5s | 0.7s | **9.5x** |
| [**tRPC**](https://github.com/trpc/trpc) (server + client) | 18,000 | 5.5s | 0.6s | **9.1x** |
| [**rxjs**](https://github.com/ReactiveX/rxjs) (observable)| 2,100 | 1.1s | 0.1s | **11.0x** |

この結果は、Microsoftが内部ベンチマークとして測定したものであり、一般的な開発環境でも同様の高速化が期待されます。
確かに`SpeedUp`を見ると、タイトルの通り10倍近くの高速化が期待できますね！

## エディターの応答速度の向上
プロジェクトの規模が大きくなるにつれ、「**エディターの起動**」や「**補完のレスポンスが遅くなる**」 という課題がありました。  
特にVS Code のような大規模コードベースでは、**型情報のロードがボトルネックになる** ことがありました。

TypeScriptのコンパイラは、単に **コードをビルドするだけでなく、エディターの言語サービス（LSP）** [^2]にも影響を与えます。  
例えば、エディターを開いたときに型情報を解析し、補完・エラーチェック・リファクタリングを提供するのは、このコンパイラが裏で処理を行っているからです。

### この「ロード時間」とは？
ここでいう **ロード時間** とは、具体的に次の **2つの時間** を指します。

#### 1. *`tsc` コマンドが型チェックを実行する際の型情報の読み込み時間*
#### 2. *IDEでプロジェクトを開いたときに `LSP`サーバーがTypeScriptの型情報を読み込む時間*

この処理が重くなると、*エディターの補完が遅れたり*、プロジェクトの*読み込みに時間がかかる* 原因になります。  
特に **大規模プロジェクトでは、エディターを開いてから正常に型情報をロードするまでの時間が長くなる**ため、このような原因を解消することでDXの改善にも繋がります。

### **VS Codeのプロジェクトロード時間が8倍高速化**
> Visual Studio Code codebase as a benchmark, the current time to load the entire project in the editor on a fast computer is about 9.6 seconds. This drops down to about 1.2 seconds with the native language service, an 8x improvement in project load time in editor scenarios. 　　*引用*：[A 10x Faster TypeScript – Microsoft DevBlogs](https://devblogs.microsoft.com/typescript/typescript-native-port/#editor-speed)

Microsoftのベンチマークでは、VS Code のコードベースのプロジェクトロード時間が 9.6 秒 → 1.2 秒 に短縮（約8倍の改善）されたことが確認されています。

これにより、**型情報のロードが大幅に高速化し、エディターの応答速度が劇的に改善される** ことが期待されます。

:::note
**🖊️ このセクションで伝えたいこと**
*単にコンパイルが速くなるだけでなく、エディターでの作業も格段に快適になる* というのが **`tsgo`** の魅力です！
:::


## **メモリ使用量の最適化**
TypeScriptコンパイラの `tsgo` への移植では、まだ完全なメモリ最適化が行われていないそうですが、それでも既存の TypeScript実装（`tsc`）と比較して、**メモリ使用量が約半分になる** とのことです。

特にCI/CD 環境では、コンパイラのメモリ消費がビルド時間に影響を与えることが多いため、「*CIでメモリ不足に悩まされることが少なくなる*」という点は非常に大きなメリットです。

また、開発環境でもメモリ使用量が減ることで、**エディターや他の開発ツールの動作が軽くなる** ことが期待されます。  
さらに最適化が進めば、**より軽量で高速なコンパイラ** として、開発環境の負荷をさらに軽減できる可能性があります。

# TypeScript 7.0の今後の展望について
現在、TypeScriptの最新バージョンは**5.8** で、次期バージョンである **5.9** のリリースが目前に迫っています。  
続く **TypeScript 6.0** では、従来のJavaScriptベースの実装が維持される一方で、**将来のネイティブ移行を見据えた非推奨機能の整理や、一部の破壊的変更** が予定されています。

## **TypeScript 7.0への移行計画**
`tsgo` を用いた **Go言語ベースのネイティブ実装** は、現在の`tsc`と同等の機能を実現した時点で、**TypeScript 7.0として正式リリース** される見込みです。 
ただし、**TypeScript 7.0はまだ開発中であり、正式なリリース時期や詳細は今後発表** される予定です。

当面の間、Microsoftは以下のように **2つの実装を並行して提供** する方針です。

| **バージョン** | **実装方式** | **コードネーム** | **備考** |
|--------------|------------|-------------|---------|
| **TypeScript 6.x** | JavaScriptベース (`tsc`) | **Strada** | 現在の実装が継続 |
| **TypeScript 7.x** | Goベース (`tsgo`) | **Corsa** | ネイティブ実装 |


## TypeScript 6と7の並行サポート
TypeScript 7.0 の **ネイティブ実装が十分に成熟するまでは、TypeScript 6.x（JavaScript版）も引き続きサポート** される予定です。  
そのため、プロジェクトの状況に応じて、次のような選択が可能です。

- **新しいTypeScript 7 (`tsgo`) に移行できるプロジェクト** → 速さ・メモリ効率向上の恩恵を受けられる  
- **TypeScript 6 (`tsc`) の機能に依存するプロジェクト** → 引き続き 6.x を利用しつつ、移行の準備を進める  

Microsoftの戦略としては、**TypeScript 7.x への移行を推奨しつつ、TypeScript 6.x も当面の間は並行して運用可能にする** という方針です。  
将来的には、開発者がTypeScript 7.xに移行したり、必要に応じてTypeScript 6.xに戻したりできる仕組みを整えることを目標にしているようです。


:::note 
**📌 まとめ**
- **現在の最新バージョンはTypeScript 5.8、TypeScript 5.9が間もなくリリース**
- **TypeScript 6.x はJavaScriptベース (`tsc`) の実装が継続**
- **TypeScript 7.0 はGoベース (`tsgo`) になり、正式リリースは現行機能と同等になり次第**
- **「Strada (JS)」と「Corsa (Go)」の2つのコードネームで開発が進行**
- **移行がスムーズにできるよう、TypeScript 6.x も並行してサポート予定**
:::

## `tsgo` はBun、Denoなどとどのように共存していくのか
`tsgo` は、既存の TypeScript ランタイム（Bun、Deno）などとどのように共存するのでしょうか？  
結論づけるのは難しいですが、以下のように簡単にまとめました。


### **Bunとの関係**
🤔 **Bun は TypeScript を JIT コンパイルできるため、`tsgo` とは設計思想が異なる**  
- `tsgo` は **開発時の型チェックとオフラインコンパイルに特化**  
- Bun は TypeScript を JIT で変換し、即時実行できるため、`tsgo` のようなオフラインコンパイルとは根本的に異なる
- そのため、Bun の TypeScript 処理が `tsgo` に置き換わる可能性は低い  
- ただし、Bun が `tsgo` を型チェック専用のバックエンドコンパイラとして利用する可能性はあるかも？

📌 **予測**  
**Bun は `tsgo` とは異なるアプローチを取るため、すぐに統合されることはない**  
ただし、**開発の選択肢として `tsgo` を利用できる可能性はある**

---

### **Denoとの関係**
🤔 **Deno は Rust (`swc`) ベースの TypeScript コンパイルを採用しているが、今後 `tsgo` に置き換わる可能性はあるのか？** 
Denoは従来、V8 で TypeScriptを直接実行するのではなく、事前に JavaScript に変換してキャッシュする方式を取っていました。  
現在は `swc`（Rust製の高速TypeScriptコンパイラ）を採用し、**TypeScript を事前に JavaScript に変換する処理を最適化** しています。

- `tsgo` を Deno に組み込むと、Deno のシングルバイナリに **Goのコンパイラが追加される可能性**  
- Deno は TypeScript の標準ライブラリをZIP圧縮してバイナリに埋め込んでいるが、`tsgo` を導入するとGoのバイナリも含めることになる？
- 一部の TypeScript の処理を `tsgo` にオプションとして切り替えられる可能性

📌 **予測**  
**Deno は当面 `swc` を維持するが、`tsgo` を一部の処理(型チェッカー)に利用する可能性はある**  



## TypeScript 7.0 のリリースによる影響
TypeScript 7.0 のリリースによって、「**開発者体験（DX）がどのように変わるのか**」 今後の動向に注目したいですね。

特に、以下のような影響が予想されます。  
✅ **エディター（VSCode など）の型チェックが高速化し、補完のレスポンスが向上する**  
✅ **CI/CD での TypeScript コンパイル時間が短縮され、開発フローがスムーズになる**  
✅ **今後 `tsc` は `tsgo` に統合されるのか？ それとも併存する形になるのかどうか**  

`tsgo` がTypeScriptの開発環境やツール群の中で、どのような役割を担っていくのか、今後の動向に注目したいですね。


# さいごに
今回は今話題の、Microsoftが発表したTypeScriptコンパイラのGo移植「`tsgo`」について整理していきました。
大規模プロジェクトや CI/CD 環境では`tsgo`の恩恵を大きく受けるのではないかと感じました。
一方で、`Deno`など既存の TypeScriptランタイムとの統合がどのように進むのか、今後の発展に注目していきたいです!


# 参考記事
https://devblogs.microsoft.com/typescript/typescript-native-port/

https://github.com/microsoft/typescript-go

https://github.com/microsoft/typescript-go/discussions/411

https://www.youtube.com/watch?v=pNlq-EVld70

https://zenn.dev/morinokami/scraps/ea2e73e6d9c1be

https://zenn.dev/terass_dev/articles/d9335be2a69c85

https://github.com/microsoft/typescript/releases
# 脚注
[^1]:[抽象構文木について](https://ja.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E6%A7%8B%E6%96%87%E6%9C%A8)

[^2]:[LSP(Language Server Protocol)](https://github.com/Microsoft/language-server-protocol)
    - 2016年にMicrosoftが発表した、エディターとプログラム解析ツールを接続するためのプロトコル
    - JSON-RPCをベースにした通信仕様で、型情報の解析・補完・エラーチェックなどをエディターで利用できるようにする
    - エディターがコードの補完やエラーチェックを行うために利用され、VS Code などの多くのIDEで採用されている