DEV Community

HK Lee
HK Lee

Posted on • Originally published at pockit.tools

TypeScript 7 and Project Corsa: Everything You Need to Know About the 10x Faster Go Rewrite

In March 2025, Anders Hejlsberg sat in front of a camera and said something nobody expected: "We are porting the TypeScript compiler to Go."

Not Rust. Not a gradual rewrite. A full port of the TypeScript compiler, language service, and type checker — the very heart of the TypeScript ecosystem — from TypeScript to Go. Microsoft called it Project Corsa, and it's now shipping as TypeScript 7.0.

The numbers are staggering. The VS Code codebase — 1.5 million lines of TypeScript — compiles in about 78 seconds with tsc today. With the new Go-based compiler, tsgo, it takes 7.5 seconds. That's not a 2x improvement. That's 10.4x.

This isn't minor tooling drama. It's the biggest change in TypeScript's 12-year history, and it has profound implications for how we build, ship, and think about TypeScript. Let's break down everything you need to know.

Why a Rewrite? Why Now?

To understand Project Corsa, you need to understand what was breaking.

TypeScript's original compiler was written in TypeScript itself — a beautiful act of self-hosting that served the project well for over a decade. But as TypeScript became the dominant language for web development (it overtook JavaScript on GitHub in August 2025), the compiler started struggling under its own success:

The Scaling Wall

  • Enterprise codebases grew exponentially. Companies like Google, Microsoft, and Stripe now have millions of lines of TypeScript. IDE responsiveness at that scale was degrading noticeably — red squiggles appearing seconds late, autocomplete taking 2-3 seconds, project-wide renames timing out.

  • CI/CD pipelines were bottlenecked. In monorepos with hundreds of packages, tsc --build was often the slowest step in the entire pipeline, sometimes taking 10+ minutes for a full type check.

  • The single-threaded ceiling. The JavaScript runtime is fundamentally single-threaded. While Node.js has worker threads, the TypeScript compiler's architecture wasn't designed for parallelism. Every type-checking operation, every file parse, every inference — all executed sequentially on a single core, while the other 15 cores in your M4 Pro sat idle.

Why Go?

This is the question everyone asks, and it deserves a thorough answer. The team considered several alternatives:

Why not Rust? Rust would have offered maximum performance, but at enormous cost in development velocity. TypeScript's codebase is heavily functional — lots of closures, recursive data structures, and pattern matching on discriminated unions. Rust's ownership model fights this programming style constantly. The team estimated a Rust rewrite would take 3-5x longer and require completely rethinking the architecture.

Why not stay in TypeScript with WASM? They tried. The --isolatedDeclarations feature in TypeScript 5.5 was partly an experiment in making the compiler more parallelizable. But the V8 runtime's single-threaded model and garbage collection overhead meant there was a fundamental ceiling on performance.

Why Go specifically?

  1. Natural fit for the codebase. TypeScript's compiler code is surprisingly procedural and functional — not heavily object-oriented. Go's style (interfaces, first-class functions, simple data structures) maps well to the existing TypeScript compiler patterns.

  2. Goroutines for parallelism. Go's goroutine model gives the compiler cheap parallelism without the complexity of manual thread management. This is crucial for parallel type-checking across files.

  3. Predictable performance. Go's garbage collector is optimized for low-latency applications. Unlike V8's GC, which can cause unpredictable pauses, Go's GC is designed for consistent response times — exactly what you want in an IDE language service.

  4. Single binary distribution. A Go binary is self-contained. No Node.js runtime required. No npm install. Just download and run. This dramatically simplifies distribution and cold starts.

  5. Team velocity. The TypeScript team could learn Go and become productive faster than with Rust, while still getting the performance gains they needed.

What Actually Changed: The Technical Deep Dive

Project Corsa isn't just "the same compiler but faster." The rewrite involved fundamental architectural changes.

Architecture: Before and After

TypeScript 5.x/6.x (JavaScript-based):

Source Files → Scanner → Parser → Binder → Type Checker → Emitter
              ↑                                              ↓
         Single-threaded, sequential pipeline           .js + .d.ts
         Running on V8 via Node.js
         ~14MB installed size (tsc + runtime)
Enter fullscreen mode Exit fullscreen mode

TypeScript 7.x (Go-based):

Source Files → Scanner → Parser → Binder → Type Checker → Emitter
              ↑          ↑                    ↑            ↓
         Parallel    Parallel          Multi-threaded   .js + .d.ts
         file I/O    parsing          type checking
         Native binary, ~25MB standalone
         No runtime dependency
Enter fullscreen mode Exit fullscreen mode

The key architectural changes:

  1. Parallel file reading. The new compiler reads and parses files concurrently using goroutines. On a codebase with thousands of files, this alone is a 2-3x speedup.

  2. Parallel type checking. The most computationally expensive phase — type checking — is now parallel across independent modules. Files that don't depend on each other can be type-checked simultaneously. This is where the bulk of the 10x improvement comes from.

  3. Shared memory. Unlike JavaScript worker threads (which require serializing data between threads), Go goroutines share memory. The type checker can access the shared symbol table directly without costly serialization.

  4. Optimized data structures. The new compiler uses Go's native data structures (slices, maps) which have more predictable memory allocation patterns than V8's heap objects. This reduces GC pressure and improves cache locality.

The tsgo CLI

The new compiler ships as tsgo, coexisting alongside the traditional tsc:

# Traditional TypeScript compiler (still works, now TS 6.x)
npx tsc --build

# New Go-based compiler
npx tsgo --build

# Or use the standalone binary directly (no Node.js needed)
tsgo --build
Enter fullscreen mode Exit fullscreen mode

tsgo accepts the same tsconfig.json format and produces identical output. The goal is behavioral compatibility — if your code compiles with tsc, it should compile with tsgo and produce the same JavaScript and declaration files.

# Check compatibility with your project
tsgo --build --noEmit

# Compare output with existing tsc
diff <(tsc --build --listEmittedFiles) <(tsgo --build --listEmittedFiles)
Enter fullscreen mode Exit fullscreen mode

TypeScript 6.0: The Bridge Release

TypeScript 6.0 serves as a crucial bridge between the JavaScript era and the Go era:

Timeline:
TS 5.9 (Late 2025)  → Last "normal" release
TS 6.0 (Feb 2026)   → Bridge release: deprecations + preparation
TS 7.0 (Mid 2026)   → Go-based compiler (Project Corsa)
Enter fullscreen mode Exit fullscreen mode

Key TypeScript 6.0 changes that prepare for 7.0:

  • target: "es5" deprecated. TypeScript 7 will not support emitting ES5. If you still need ES5 output, use a separate transpiler (Babel, SWC, esbuild).

  • Legacy module resolution deprecated. "moduleResolution": "node" (the old one, not "node16") and "moduleResolution": "classic" are deprecated. Use "node16", "nodenext", or "bundler".

  • Default target changes. The default target is now "es2025" instead of "es5", and the default module is "nodenext".

  • Temporal API types. TypeScript 6.0 includes built-in types for the JavaScript Temporal API.

The Benchmark Reality

Let's look at real-world numbers, because the headline "10x faster" needs context.

Full Build Performance

Codebase Lines of TS tsc (TS 6.x) tsgo (TS 7.x) Speedup
VS Code 1.5M ~78s ~7.5s 10.4x
Playwright ~800K ~45s ~3.5s 12.9x
TypeORM ~350K ~28s ~2.8s 10x
Medium app (50K) 50K ~4s ~0.8s 5x
Small app (5K) 5K ~1.2s ~0.5s 2.4x

Notice the pattern: the speedup is proportional to project size. Large projects with many files benefit the most because they can exploit parallelism more aggressively. A small project with 20 files has limited opportunity for parallel work.

IDE Experience (Language Service)

This is where most developers will feel the difference:

Scenario: Opening a 500-file TypeScript project

TypeScript 6.x Language Service:
  Initial load:           4-6 seconds
  First autocomplete:     2-3 seconds  
  Go-to-definition:       500ms-1s
  Hover type info:        200-500ms
  Project-wide rename:    5-15 seconds

TypeScript 7.x Language Service:
  Initial load:           0.5-1 second
  First autocomplete:     200-400ms
  Go-to-definition:       50-150ms
  Hover type info:        30-100ms
  Project-wide rename:    1-3 seconds
Enter fullscreen mode Exit fullscreen mode

The language service improvement is arguably more impactful than the build speed. Faster IntelliSense means less waiting, fewer context switches, and a fundamentally more responsive development experience.

Memory Usage

Memory consumption: type-checking VS Code codebase

TypeScript 6.x (Node.js):
  Peak RSS:  ~4.2 GB
  Average:   ~3.1 GB

TypeScript 7.x (tsgo):
  Peak RSS:  ~1.8 GB
  Average:   ~1.2 GB

Reduction: ~57% less memory
Enter fullscreen mode Exit fullscreen mode

Go's memory model is substantially more efficient than V8's heap. This has practical implications: CI runners with less RAM, laptop development without swapping, and Docker containers with tighter memory limits.

What Breaks: Migration Concerns

TypeScript 7 aims for behavioral compatibility, but "aims for" and "achieves" are different things. Here's what you need to watch:

High Risk: Custom Transformers and Compiler Plugins

If you're using the TypeScript Compiler API (ts.createProgram, ts.transform, etc.), this is the biggest concern. The Go-based compiler exposes a different programmatic API. Custom transformers written against the JavaScript compiler API will not work with tsgo.

// ❌ This TypeScript Compiler API code won't work with tsgo
import * as ts from 'typescript';

const transformer: ts.TransformerFactory<ts.SourceFile> = (context) => {
  return (sourceFile) => {
    // Custom transformation logic
    return ts.visitEachChild(sourceFile, visitor, context);
  };
};
Enter fullscreen mode Exit fullscreen mode

Tools affected include:

  • ts-morph (popular code manipulation library)
  • ttypescript (custom transformer loader)
  • Any custom ts.LanguageServicePlugin
  • Build tools with deep TypeScript Compiler API integration

The mitigation: TypeScript 7 will expose a new cross-language API (likely via a gRPC or IPC mechanism) for programmatic access. But existing plugins need to be rewritten.

Medium Risk: Strictness by Default

TypeScript 7 enables strict: true by default. If your tsconfig.json doesn't explicitly set strict, you'll get:

// tsconfig.json  what TypeScript 7 assumes by default
{
  "compilerOptions": {
    // These are now ALL true by default:
    "strict": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "useUnknownInCatchVariables": true
  }
}
Enter fullscreen mode Exit fullscreen mode

If your codebase wasn't using strict mode, the upgrade will surface hundreds or thousands of type errors. This isn't a tsgo issue per se — it's a TS 7 policy change. Add "strict": false to your tsconfig to maintain current behavior.

Low Risk: Emit Differences

The JavaScript output from tsgo should be functionally identical to tsc, but there may be cosmetic differences:

  • Whitespace and formatting in emitted .js files might differ slightly
  • Source map column numbers could have minor variations
  • Comment preservation behavior might have edge cases

For most projects, these differences are invisible. If you have snapshot tests that compare emitted JavaScript character-by-character, they'll break. The fix is straightforward: update the snapshots.

TypeScript 6.0 Deprecations (Already in Effect)

These are already deprecated in TS 6.0 and will be removed in TS 7.0:

//  These tsconfig options are going away:
{
  "compilerOptions": {
    "target": "es5",           // Use "es2020"+ or transpile separately
    "moduleResolution": "node", // Use "node16", "nodenext", or "bundler"
    "moduleResolution": "classic", // Same  use modern resolution
    "out": "...",              // Use "outDir" instead
    "charset": "utf8"         // Removed (always UTF-8 now)
  }
}
Enter fullscreen mode Exit fullscreen mode

How to Prepare Your Project Today

You don't need to wait for TypeScript 7 GA to start preparing. Here's a practical migration checklist:

Step 1: Audit Your tsconfig.json

# Check for deprecated options
npx tsgo --build --noEmit 2>&1 | grep -i "deprecated"
Enter fullscreen mode Exit fullscreen mode

Or manually check for:

  • target: "es5" or target: "es3" → Switch to "es2020" or higher
  • moduleResolution: "node" → Switch to "node16" or "bundler"
  • module: "commonjs" → Consider "node16" or "nodenext"

Step 2: Enable Strict Mode (If You Haven't)

# See how many errors strict mode would introduce
npx tsc --strict --noEmit 2>&1 | wc -l
Enter fullscreen mode Exit fullscreen mode

If the number is manageable, enable it now. If it's thousands, consider enabling strict flags incrementally:

{
  "compilerOptions": {
    "strictNullChecks": true,     // Start here  highest value
    "noImplicitAny": true,        // Then this
    "strictFunctionTypes": true,  // Then this
    // ... add more over time
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Check Compiler API Dependencies

# Find packages that depend on the TypeScript Compiler API
grep -r "from 'typescript'" node_modules/*/src/ 2>/dev/null | head -20
grep -r "require('typescript')" node_modules/*/src/ 2>/dev/null | head -20
Enter fullscreen mode Exit fullscreen mode

Check if any of your build tools, linting plugins, or code generators have deep TypeScript Compiler API integration. Monitor their repositories for tsgo compatibility updates.

Step 4: Try tsgo on Your Project

The tsgo preview is already available:

# Install the preview
npm install -D typescript@7.0.0-beta

# Run type checking
npx tsgo --noEmit

# Compare with current tsc
time npx tsc --noEmit
time npx tsgo --noEmit
Enter fullscreen mode Exit fullscreen mode

Step 5: Update Your CI Pipeline

If you're running tsc in CI, consider the switch:

# GitHub Actions example
- name: Type Check
  run: npx tsgo --build --noEmit
  # Alternative: use the standalone binary for faster cold start
  # run: |
  #   curl -L https://github.com/nicolo-ribaudo/tc39-proposal-type-annotations/releases/... -o tsgo
  #   chmod +x tsgo
  #   ./tsgo --build --noEmit
Enter fullscreen mode Exit fullscreen mode

The Ecosystem Impact

TypeScript 7 doesn't exist in a vacuum. The ripple effects across the JavaScript ecosystem are significant.

Bundlers and Build Tools

Vite / Rolldown / esbuild / SWC: These tools handle transpilation but rely on tsc for type checking. They'll benefit from faster tsgo type checks in CI, but their core functionality is unaffected since they don't use tsc for emit.

webpack (ts-loader / fork-ts-checker-webpack-plugin): These plugins use the TypeScript Compiler API directly and will need updates for tsgo compatibility. Watch for migration guides from their maintainers.

Turbopack: Already has first-class TypeScript support independent of tsc. The tsgo integration for type checking is being tracked.

IDEs and Editors

VS Code: Will adopt the new Go-based language service. Expect significantly faster IntelliSense, especially in large workspaces. The VS Code team is already dogfooding tsgo on the VS Code codebase itself.

WebStorm/IntelliJ: JetBrains has their own TypeScript integration. They'll need to integrate with the new tsgo language service API.

Neovim (via typescript-language-server): The typescript-language-server npm package wraps tsserver. It will need updates to work with the new Go-based language service, or could potentially integrate with tsgo directly.

Frameworks

Next.js / Nuxt / Remix / SvelteKit: These frameworks run tsc for type checking during build. Replacing tsc with tsgo should be a drop-in improvement with no code changes needed.

Angular: Angular's compiler (ngc) builds on top of the TypeScript Compiler API extensively. This is one of the most complex migrations in the ecosystem. The Angular team is actively working on tsgo compatibility.

The Controversial Question: Is TypeScript Still "TypeScript"?

The announcement sparked philosophical debates in the community. Some argued that a TypeScript compiler not written in TypeScript undermines self-hosting — a point of pride for languages. Others pointed out the irony of a language designed for JavaScript developers now having its core tooling in Go.

Here's the pragmatic take: TypeScript the language isn't changing. Your .ts files, your type annotations, your tsconfig.json — all identical. The compiler is an implementation detail. Just as Python's most common implementation is CPython (written in C), TypeScript is adopting a more performant implementation language while keeping the user-facing language the same.

And honestly? The community voted with benchmarks. When developers saw their 78-second builds drop to 7.5 seconds, the debates got a lot quieter.

What About Self-Hosting?

TypeScript 6.0 remains the last self-hosted version and will continue to receive critical fixes. It's not disappearing. For environments where Go binaries aren't available, or for learning the compiler internals in TypeScript, the JavaScript-based compiler remains an option.

But for production use, tsgo will quickly become the standard. Performance matters more than philosophical purity.

The Bigger Picture: The "Rewrite It in a Systems Language" Trend

TypeScript 7 is part of a broader trend in JavaScript tooling:

Tool Original Language Rewritten In Speedup
TypeScript 7 (tsgo) TypeScript Go 10x
Rolldown (replacing Rollup) JavaScript Rust 10-15x
esbuild Go 100x vs webpack
SWC (replacing Babel) JavaScript Rust 20x
Biome (replacing ESLint+Prettier) JavaScript Rust 25x
Oxc (parser/linter) JavaScript Rust 50x
Turbopack JavaScript Rust 10x vs webpack
Rspack JavaScript Rust 5-10x vs webpack

The JavaScript ecosystem is effectively outsourcing its performance-critical infrastructure to systems languages while keeping the user-facing APIs in JavaScript/TypeScript. The developer experience stays the same (write TypeScript, use familiar configs), but the underlying machinery is native code.

This isn't JavaScript "dying." It's JavaScript specializing. The language is focusing on what it's best at — application logic, UI, business rules — while delegating compilation, linting, bundling, and formatting to tools that can exploit multi-core CPUs and efficient memory management.

What Happens Next

Short Term (Q1-Q2 2026)

  • TypeScript 7.0 beta available for testing
  • tsgo CLI installable via npm
  • Major bundlers and frameworks begin tsgo integration
  • Community discovers and reports edge case differences

Medium Term (Q3-Q4 2026)

  • TypeScript 7.0 stable release
  • VS Code switches to Go-based language service by default
  • Most framework CLIs offer tsgo as the default type checker
  • Plugin ecosystem begins migrating to new API

Long Term (2027+)

  • TypeScript 6.x (tsc) enters maintenance mode
  • New TypeScript features implemented in Go first
  • Potential for new capabilities that were impossible in the JavaScript-based compiler (e.g., whole-program optimizations across package boundaries)

Conclusion

TypeScript 7 and Project Corsa represent the biggest shift in TypeScript since its creation. The move from a self-hosted JavaScript compiler to a Go-based native binary isn't just a performance optimization — it's an architectural evolution that unlocks fundamentally new capabilities.

For most developers, the upgrade will be anticlimactic in the best way: your TypeScript code stays the same, your tsconfig stays the same, and everything just gets faster. Much faster.

For tool authors and framework developers, there's real migration work ahead, particularly around the Compiler API changes. Start testing with tsgo --noEmit today.

For the ecosystem as a whole, Project Corsa validates a pattern we've been watching for years: the JavaScript toolchain is becoming polyglot, with systems languages handling performance-critical paths while TypeScript and JavaScript handle developer-facing logic.

The bottom line? TypeScript 7 is what happens when a good language gets a great compiler. And if your 78-second builds dropping to 7.5 seconds doesn't make you smile, nothing will.


🔒 Privacy First: This article was originally published on the Pockit Blog.

Stop sending your data to random servers. Use Pockit.tools for secure utilities, or install the Chrome Extension to keep your files 100% private and offline.

Top comments (0)