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.jsonWhat 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 + referencesIf 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 buildMistake 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 --noEmitThis 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:
- TypeScript Go — GitHub Repository: https://github.com/microsoft/typescript-go
- TypeScript Blog — Announcing TypeScript Go: https://devblogs.microsoft.com/typescript/typescript-native-port/
Related Articles
pnpm vs npm vs yarn vs bun: The Real Comparison Nobody Gives You in 2025
I used all four in real projects. One wrecked a monorepo at 3am. Another saved my ass in production. Here's the unfiltered truth about every major package manager in 2025.
React 19 use() hook and Suspense: when it replaces useEffect and when it throws you into a worse loop
React 19's use() hook promises to replace useEffect for data fetching. That promise is partially true. There are two patterns with Suspense and error boundaries where the behavior isn't what you expect and the cycle gets messier. I'll tell you exactly when to migrate and when not to.
TypeScript strict mode: the 6 tsconfig options that actually matter in production and when to enable them
strict: true is not enough — and it's not the whole story. A flag-by-flag breakdown of what each strict mode option actually does, what bugs it prevents, and the order to enable them in an existing codebase.
Comments (0)
What do you think of this?
Drop your comment in 10 seconds.
We only use your login to show your name and avatar. No spam.