DEV Community

Cover image for tsgo: what changes in the TypeScript compiler rewritten in Go and what it means for real projects
Juan Torchia
Juan Torchia Subscriber

Posted on • Originally published at juanchi.dev

tsgo: what changes in the TypeScript compiler rewritten in Go and what it means for real projects

tsgo: what changes in the TypeScript compiler rewritten in Go and what it means for real projects

I made the mistake of dismissing tsgo as hype before actually reading it. I saw the "10x faster" headline and mentally filed it next to JavaScript framework benchmarks — real numbers in a context that has nothing to do with my work. It only took opening the official repository and the TypeScript team's announcement to understand that this time the story is different. And that it's worth understanding exactly what changed, what hasn't yet, and when it actually makes sense to explore the migration.

My thesis is simple: tsgo is a legitimate technical bet with public evidence behind it, but the beta has documented limitations that most enthusiastic posts quietly skip. The criterion for migrating today isn't whether the number looks attractive — it's whether your CI spends more than 5 minutes on type-checking. If you don't hit that threshold, wait for stable and sleep easy.

tsgo typescript compiler go: what it is and where it came from

The official project lives at github.com/microsoft/typescript-go. This isn't a fork or a community experiment — it's the TypeScript team itself porting the compiler to native Go, with the declared goal of leveraging real parallelism and eliminating V8 overhead.

The official announcement on the TypeScript Blog is clear about the reasoning: JavaScript has a ceiling on compilation speed because it runs on a general-purpose runtime. Go lets you compile to a native binary, manage goroutines for genuine parallelism, and avoid V8's garbage collector pressure. The result according to the team's own measurements: compilations that take tens of seconds with classic TypeScript drop to a few seconds or less.

The important thing is that tsgo does not change the type system. TypeScript's semantics — the same errors, the same inferences, the same strict behavior — stay identical. What changes is the speed at which you get to those results.

# Experimental installation per the official repo
# Not on stable npm yet — follow the repo's README
git clone https://github.com/microsoft/typescript-go
cd typescript-go

# Build the binary (requires Go installed)
go build ./cmd/tsgo

# Run type-check on a project
./tsgo --project path/to/tsconfig.json
Enter fullscreen mode Exit fullscreen mode

What limitations the beta has today

This is where most posts fall short. The official repository's roadmap explicitly documents what isn't ready in the beta:

Language Service (LSP) incomplete. Editor integration — VS Code, Neovim, any LSP client — is in progress but doesn't have parity with tsc. That means you can't replace the language server that gives you hover types, go-to-definition, and autocomplete today. The CLI type-check is the most mature piece.

Build mode and project references. Support for tsc --build with composite: true and references between packages in a monorepo is partially implemented. If you're using pnpm workspaces with multiple linked tsconfig.json files, you'll hit edge cases.

TypeScript plugins. The plugins in tsconfig.json that many frameworks use internally — Next.js ships its own — don't have guaranteed support yet.

Code transformations. tsgo in beta is a type-checker, not a full transpiler. It doesn't replace tsc when you need to emit .js from .ts with transformations. That's still territory for the original compiler or tools like esbuild/swc.

// Typical tsconfig.json in a Next.js project with strict mode
// What tsgo can type-check today (CLI)
{
  "compilerOptions": {
    "strict": true,
    "noEmit": true,         // ← "type-check only, no emit" mode — the most mature case in tsgo
    "target": "ESNext",
    "moduleResolution": "Bundler",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}
// What's NOT ready: plugins like Next.js's own, complex composite + references
Enter fullscreen mode Exit fullscreen mode

If you have strict: true enabled — and if you're not sure why you should, I have a post on the tsconfig options that actually matter in production — tsgo respects exactly that semantics. The port doesn't relax or change the checks.

The common mistakes when evaluating tsgo

Mistake 1: comparing the number without project context. The "10x" comes from benchmarks on large codebases. On a 50-file project where tsc --noEmit takes 8 seconds, the jump will be noticeable but not dramatic. On a monorepo with 500+ files where type-checking in CI takes 4–6 minutes, the difference concretely changes your pipeline.

Mistake 2: assuming it replaces the entire toolchain. tsgo in beta is a type-check binary. It doesn't replace esbuild, swc, or next build. Most modern monorepos already separated type-checking from transpilation — if yours hasn't, this is the moment to do it regardless of tsgo.

# Separating type-check from build in CI — recommended pattern today
# Step 1: type-check (candidate for tsgo when stable)
pnpm tsc --noEmit --project tsconfig.json

# Step 2: build/transpilation (keep using tsc or next build, not tsgo yet)
pnpm next build
Enter fullscreen mode Exit fullscreen mode

Mistake 3: ignoring the Language Service. Several enthusiastic posts recommend switching VS Code's typescript.tsdk to point at tsgo. The result today is inconsistent — some features work, others don't. Unless you're deliberately experimenting, don't do it in an environment where you need to actually develop.

Mistake 4: losing sight of the fact that plugins matter. Next.js 15+ ships its own TypeScript plugin to correctly type Server Component props and generateMetadata parameters. If tsgo doesn't load it, you lose those checks. That's not a tsgo problem — it's a documented beta limitation you need to track before adopting it.

Decision matrix: when to explore tsgo today

Not every tooling decision needs a spreadsheet. This one does need clear criteria because the cost of a premature migration is real: breaking your editor's feedback loop exactly when you need it most.

Situation Recommendation
CI type-check > 5 minutes Worth exploring tsgo in a separate job and comparing
CI type-check < 2 minutes Wait for stable — no urgent gain
Monorepo with complex project references Wait — documented partial support
Next.js project with its TS plugin Wait — plugins not guaranteed in beta
Pure type-check (--noEmit) in a separate CI job Most mature case to try today
Need Language Server in your editor Not yet — LSP incomplete

The only scenario where I see immediate value is a CI pipeline where type-checking is the documented bottleneck and you can run tsgo in a parallel job without touching the main build. That way you explore without risk.

# Example parallel job in GitHub Actions to evaluate tsgo
# Without touching the main build
jobs:
  typecheck-experimental:
    runs-on: ubuntu-latest
    continue-on-error: true  # doesn't block the pipeline if tsgo fails
    steps:
      - uses: actions/checkout@v4
      - name: Install Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.22'
      - name: Clone and build tsgo
        run: |
          git clone https://github.com/microsoft/typescript-go /tmp/tsgo
          cd /tmp/tsgo && go build ./cmd/tsgo
      - name: Measure type-check time with tsgo
        run: |
          time /tmp/tsgo/tsgo --project tsconfig.json
      - name: Measure type-check time with tsc (for comparison)
        run: |
          time pnpm tsc --noEmit
Enter fullscreen mode Exit fullscreen mode

This approach has one concrete advantage: you get real data from your project, not from Microsoft's benchmark. That difference matters.

What you can't conclude without your own experiment

The uncomfortable thing about this topic is that the public evidence backs the speed claim but can't tell you how much your specific pipeline will improve. It depends on file count, type complexity, whether you're using heavy conditional types, how many paths your tsconfig has, and whether you have plugins tsgo won't load.

What you can conclude without experimenting:

  • tsgo will not change error semantics — same type system specification
  • tsgo is not a drop-in replacement today — documented limitations in the official repo
  • The technical bet of rewriting in Go has solid justification beyond the marketing: native parallelism, binary without V8, different memory management

What you need to measure yourself:

  • Real time gains on your specific codebase
  • Whether the plugins you use are supported
  • Language Service behavior in your editor

Without those three measurements, any claim of "migrate it now" or "it's worthless" is noise.

FAQ: tsgo typescript compiler go

Does tsgo completely replace tsc today?
No. In the current beta, tsgo is primarily a CLI type-checker (--noEmit). It doesn't replace code emission, TypeScript plugins, and doesn't have full Language Service parity for editors. The official repository documents the roadmap with what's still missing.

Is tsgo's type system identical to the original TypeScript?
Yes, that's the project's premise. The Go port replicates the same type semantics — the same errors, the same inferences, the same strict behavior. If you find a difference, it's a bug in the port, not a feature.

Does it work with Next.js?
Partially. Basic type-checking works, but the TypeScript plugin Next.js includes to type Server Components and metadata isn't guaranteed in the beta. For production Next.js projects, wait until plugin support is stable.

Is it worth trying in a monorepo with pnpm workspaces?
Depends on the size. If you have project references (composite: true) between packages, support is partial per the official documentation. If you're simply running tsc --noEmit on the root, that's the most mature scenario to experiment with.

When will it hit stable?
The official repository's roadmap has no public date. The signal to watch for: complete LSP, verified plugin support, and documented parity with tsc. Follow the repo — the milestones are public.

Should I switch VS Code's typescript.tsdk to tsgo now?
I wouldn't do it in an active development environment. The tsgo Language Service in beta has incomplete features that will break hover types and autocomplete in specific cases. If you want to experiment, do it on a dedicated branch with that explicit purpose.

My take and the one concrete next step

tsgo is the most technically interesting move in the TypeScript ecosystem in years. Not because the "10x" number is magic, but because the real bottleneck of the compiler was always the JavaScript runtime — and that limitation now has a serious answer with public evidence behind it.

What I don't buy is the enthusiasm that ignores the documented limitations. The current beta has a clear scope: CLI type-checking on projects without complex plugins. That's not nothing — for many CI pipelines it's exactly the critical use case — but it's also not the full replacement some posts present it as.

My practical recommendation: if type-checking is the documented bottleneck in your CI, set up a parallel job with continue-on-error: true, measure the delta on your real codebase, and make the decision with your own data. If you don't have that problem today, close this tab and revisit it when the team announces stable. There's no urgency.

The next step for you is exactly one thing: go to the official repository and check the open issues for the features you actually use. That's where the real information is — not in the headlines.


Original sources:


This article was originally published on juanchi.dev

Top comments (0)