Monday, August 24, 2026

The Go Rewrite Migration Information


TypeScript 7.0 RC marks probably the most important architectural shift within the compiler’s historical past. Your entire TypeScript compiler has been rewritten in Go, a challenge internally codenamed “Corsa,” delivering as much as roughly 9-10x sooner construct occasions throughout real-world codebases relying on challenge measurement (see benchmark desk). This migration information walks by way of the concrete steps wanted to undertake the Go rewrite with out breaking current initiatives, masking set up, configuration modifications, construct pipeline updates, and the sting instances that journey groups up throughout the transition.

Learn how to Migrate to TypeScript 7.0 RC (tsgo)

  1. Audit your present TypeScript model and all packages that rely upon the compiler API (ts-loader, ts-node, ts-morph, and so forth.).
  2. Set up the @typescript/native bundle from npm alongside your current typescript bundle, pinned to an actual RC model.
  3. Delete all stale .tsbuildinfo recordsdata, for the reason that Go compiler’s incremental artifacts are incompatible with the JS compiler’s.
  4. Run tsgo --noEmit in opposition to your challenge and evaluate diagnostic codes with tsc output to catch behavioral divergences.
  5. Replace tsconfig.json by eradicating preserveConstEnums and noting unported options like declarationMap.
  6. Regulate construct scripts and CI pipelines to invoke tsgo for type-checking whereas retaining tsc as a parallel security web.
  7. Configure your editor (VS Code TypeScript Native Preview extension) to make use of the Go-based language service.
  8. Validate by operating each compilers in CI throughout a transition interval earlier than dropping the legacy tsc dependency.

Desk of Contents

What Modified Beneath the Hood: The Go-Based mostly Compiler

Why the Rewrite Occurred

The JavaScript-based TypeScript compiler had hit a efficiency ceiling that incremental optimizations may now not meaningfully handle. The one-threaded nature of the Node.js runtime meant that type-checking, probably the most computationally costly part of compilation, couldn’t use trendy multi-core processors. Giant monorepos with hundreds of recordsdata routinely confronted construct occasions measured in minutes, and the compiler consumed extra reminiscence as challenge file counts grew.

The Corsa challenge got down to remedy this by rewriting the compiler in Go, focusing on three objectives: native concurrency for parallel type-checking, ~60-70% decrease peak reminiscence utilization by way of Go’s extra environment friendly reminiscence mannequin (see benchmarks beneath), and sooner uncooked execution by compiling to a local binary fairly than decoding JavaScript. Anders Hejlsberg introduced the hassle publicly in early 2025. The crew shipped an alpha, then reached Launch Candidate standing. RC standing means the TypeScript crew considers the compiler feature-complete for its goal scope and appropriate for broader testing, although some options stay unported and behavioral edge instances are nonetheless being resolved. RC software program mustn’t gate manufacturing releases and not using a parallel tsc security web.

The Corsa challenge got down to remedy this by rewriting the compiler in Go, focusing on three objectives: native concurrency for parallel type-checking, ~60-70% decrease peak reminiscence utilization by way of Go’s extra environment friendly reminiscence mannequin, and sooner uncooked execution by compiling to a local binary fairly than decoding JavaScript.

Architectural Variations at a Look

The previous compiler ran as a Node.js course of, executing JavaScript (transpiled from TypeScript supply), constrained to a single thread for type-checking. The brand new compiler ships as a standalone native binary constructed from Go, able to concurrent type-checking throughout a number of goroutines.

What stayed the identical: TypeScript language semantics, the sort system’s habits, and tsconfig.json compatibility. Present TypeScript code doesn’t want syntax modifications. What modified: the distribution mannequin shifted from an npm bundle containing JavaScript to a local binary (additionally installable through npm as a wrapper), and the Go rewrite doesn’t expose the programmatic API that instruments like ts-node and customized transformers relied on.

FacetTypeScript 5.x/6.xTypeScript 7.0 RC
CLI invocationnpx tscnpx tsgo or standalone tsgo
RuntimeNode.js (JavaScript)Native Go binary
Distributionnpm bundle (typescript)npm wrapper (confirm bundle title at typescript-go releases) + standalone binary
Kind-checkingSingle-threadedConcurrent
Programmatic APIts.createProgram(), and so forth.Not obtainable; language service protocol (possible LSP-based, affirm in official documentation) deliberate
tsconfig.jsonTotally supportedTotally appropriate (with minor possibility modifications)

Pre-Migration Evaluation

Checking Your Present Setup

Earlier than migrating, catalog your actual TypeScript model, all packages that rely upon it, and whether or not any tooling calls the TypeScript Compiler API programmatically. Dependencies like ts-loader, ts-node, ts-jest, and @typescript-eslint/parser every work together with TypeScript in a different way, and their compatibility with 7.0 RC varies.

{
  "scripts": ts-jest
}

For npm v7+, add --depth=Inf if wanted: npm ls --depth=Inf typescript. Output format modified between npm v6 and v7+.

Working npm run audit:ts-deps surfaces each bundle within the dependency tree that straight or transitively will depend on TypeScript, supplying you with a transparent stock of what wants verification.

Recognized Limitations within the RC

The RC doesn’t but assist declaration map era (--declarationMap). Advanced composite challenge configurations with round references could produce totally different habits in challenge references. The --build mode (tsc -b) has gaps in multi-project orchestration eventualities. The plugin ecosystem that relied on the JavaScript-based compiler API has no direct equal. Editor integration by way of the language service works in VS Code through an up to date extension, however JetBrains has not introduced a tsgo integration date as of mid-2025.

Step-by-Step Migration Information

Step 1: Putting in TypeScript 7.0 RC

The compiler is on the market by way of npm or as a standalone binary obtain. Confirm the precise npm bundle title and binary obtain URLs on the typescript-go releases web page earlier than putting in, as these could change earlier than steady launch.





VERSION=""  
npm set up --save-dev @typescript/native@"$VERSION"


npx tsgo --version

For the standalone binary, all the time confirm the SHA-256 checksum of downloaded binaries in opposition to the worth printed on the official releases web page earlier than executing them. Don’t run binaries downloaded with out checksum verification.


curl --proto '=https' --tlsv1.2 -fsSL 
  https://typescript.azureedge.web/releases/7.0.0-rc/tsgo-darwin-arm64 
  -o /usr/native/bin/tsgo


EXPECTED_SHA256=""
ACTUAL_SHA256=$(shasum -a 256 /usr/native/bin/tsgo | awk '{print $1}')

if [ "$ACTUAL_SHA256" != "$EXPECTED_SHA256" ]; then
  echo "ERROR: Checksum mismatch. Anticipated: $EXPECTED_SHA256  Acquired: $ACTUAL_SHA256" >&2
  rm -f /usr/native/bin/tsgo
  exit 1
fi

chmod +x /usr/native/bin/tsgo
tsgo --version

The standalone binary URL proven is for macOS arm64. Confirm the right URL on your OS and structure (Linux x86_64, Home windows, and so forth.) on the releases web page.

To run alongside an current TypeScript 5.x or 6.x set up, hold the typescript bundle in devDependencies and add the Go-based bundle individually. Each binaries land in node_modules/.bin, so you’ll be able to run them facet by facet.

Step 2: Working Your First Construct with tsgo

Level the brand new compiler at an current challenge by operating tsgo within the challenge root. It reads the identical tsconfig.json routinely.


$ npx tsc --diagnostics
Information:            387
Strains:          94521
Nodes:         412893
Complete time:    12.4s


$ npx tsgo --diagnostics
Information:            387
Strains:          94521
Nodes:         412893
Complete time:     1.3s

The diagnostics output format differs barely. Error messages use the identical diagnostic codes however wording differs; diagnostic codes stay similar, so match on codes, not message textual content. The --diagnostics flag works in each compilers, making side-by-side comparability simple.

Step 3: Updating tsconfig.json

Most tsconfig.json recordsdata work with out modifications. Nonetheless, a number of choices warrant consideration.

{
  "compilerOptions": {
    // Unchanged — these work identically in 7.0 RC
    "goal": "ES2022",
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "outDir": "./dist",

    // Nonetheless supported however restricted in RC:
    "declarationMap": true, // ⚠️ RC generates .d.ts recordsdata usually however does NOT generate .d.ts.map recordsdata. IDE go-to-definition for library shoppers can be affected.

    // Parallel type-checking is on by default; no tsconfig flag is required.
    // See launch notes for future opt-in choices.

    // Take away if current — now not acknowledged:
    // "preserveConstEnums" is eliminated. The Go compiler all the time emits const enum
    // declarations in output (equal to the previous preserveConstEnums: true).
    // In case your code relied on const enum *inlining* (the default
    // preserveConstEnums: false habits), take a look at your JS runtime output rigorously.
  },
  "embody": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

The strict flag and all its constituent flags (strictNullChecks, strictFunctionTypes, and so forth.) behave identically. The Go compiler drops the preserveConstEnums possibility as a result of it all the time emits const enum declarations in output (equal to the previous preserveConstEnums: true). In case your construct relied on const enum inlining throughout module boundaries (the default habits when preserveConstEnums was false), it is a behavioral change. Check your runtime JS output rigorously.

Step 4: Adapting Your Construct Pipeline

Tasks utilizing bundlers really feel this alteration solely within the type-checking step, not transpilation. Instruments like esbuild, Vite, and SWC deal with their very own transpilation and solely invoke TypeScript for type-checking.

Delete stale incremental artifacts earlier than the primary tsgo run. The Go compiler’s .tsbuildinfo recordsdata should not appropriate with these from the JS compiler:


discover . 
  -maxdepth 5 
  -name '*.tsbuildinfo' 
  -not -path '*/node_modules/*' 
  -print


discover . 
  -maxdepth 5 
  -name '*.tsbuildinfo' 
  -not -path '*/node_modules/*' 
  -delete
{
  "scripts": {
    "typecheck": "tsgo --noEmit",
    "typecheck:legacy": "tsc --noEmit",
    "typecheck:evaluate": "time npm run typecheck:legacy; time npm run typecheck",
    "construct": "tsgo --noEmit && vite construct",
    "watch": "tsgo --watch --noEmit",
    "lint": "eslint . --ext .ts,.tsx",
    "ci:typecheck": "tsgo --noEmit --diagnostics"
  }
}

The "construct" script above makes use of tsgo --noEmit for type-checking solely earlier than handing off to Vite for transpilation and bundling. Omit --noEmit provided that you plan tsgo to emit JS output straight. The "typecheck:evaluate" script makes use of ; as an alternative of && in order that tsgo timing runs even when tsc exits non-zero attributable to sort errors.

CI/CD pipelines profit as a result of the native binary eliminates the Node.js runtime dependency for type-checking. CI photos can shrink provided that you employ the standalone binary and no different Node.js tooling stays required. The binary should match the CI runner’s OS and structure. Cache the tsgo binary alongside node_modules, and delete any stale .tsbuildinfo recordsdata when switching compilers, for the reason that Go compiler’s incremental artifacts are incompatible with these from the JS compiler.

ts-loader customers: the loader’s transpileOnly: true mode continues to work because it bypasses type-checking completely. ts-loader’s full type-check mode calls the JS compiler API, which tsgo doesn’t expose. Confirm compatibility together with your particular ts-loader model.

Step 5: Updating Editor and IDE Configuration

In VS Code, the TypeScript crew gives an up to date extension that makes use of the Go-based language service. Seek for the TypeScript Native Preview extension on the VS Code Market (confirm the present extension title, as it could differ between releases), then configure your .vscode/settings.json:

{
  "typescript.tsserver.useTsgo": true
}

Confirm this setting key in opposition to the extension’s README; it could differ between extension variations. If VS Code reveals a yellow warning on the setting or the important thing doesn’t seem within the Settings UI search, seek the advice of the extension documentation for the right configuration.

JetBrains IDEs (WebStorm, IntelliJ IDEA) don’t but supply native tsgo language service integration as of the RC. These IDEs proceed to make use of the JavaScript-based language service. Groups utilizing JetBrains can nonetheless run tsgo for command-line type-checking whereas counting on the bundled TypeScript service for editor options.

Dealing with Breaking Modifications and Edge Circumstances

Behavioral Variations to Watch For

The Go compiler produces similar sort errors for the overwhelming majority of code, however the RC has identified divergences in narrowing habits inside complicated conditional sort patterns. The Go sort resolver evaluates some deeply nested conditional varieties with infer clauses in a distinct order, which may change decision outcomes.

Error message wording differs in lots of instances. The diagnostic codes stay the identical (e.g., TS2322 for sort task errors), however the explanatory textual content could also be phrased in a different way. Any tooling that parses error message textual content fairly than diagnostic codes will want updates.

To report discrepancies, the TypeScript crew tracks behavioral variations on the microsoft/typescript-go GitHub repository. Seek for points tagged with divergence-related labels (confirm present label names on the repository). Working each compilers in parallel throughout a validation interval is strongly beneficial. A easy CI step can implement this:

npx tsc --noEmit 2> legacy-errors.txt
npx tsgo --noEmit 2> native-errors.txt


diff 
  <(grep -oE 'TS[0-9]+' legacy-errors.txt | kind | uniq -c | kind -k2) 
  <(grep -oE 'TS[0-9]+' native-errors.txt  | kind | uniq -c | kind -k2)

Programmatic API Migration

The TypeScript Compiler API (ts.createProgram, ts.createSourceFile, ts.forEachChild, and so forth.) doesn’t exist within the Go rewrite. Instruments constructed on this API, together with ts-morph, customized AST transformers, and code era pipelines, can’t use tsgo as a drop-in substitute.

The TypeScript crew has outlined plans for a language service protocol that exterior instruments can talk with over IPC, however the crew has not finalized this protocol within the RC. For now, initiatives counting on the programmatic API ought to proceed utilizing the JavaScript-based typescript bundle for these particular duties whereas utilizing tsgo for build-time type-checking.

The TypeScript Compiler API (ts.createProgram, ts.createSourceFile, ts.forEachChild, and so forth.) doesn’t exist within the Go rewrite. Instruments constructed on this API, together with ts-morph, customized AST transformers, and code era pipelines, can’t use tsgo as a drop-in substitute.


import * as ts from "typescript";

const program = ts.createProgram(["src/index.ts"], { strict: true });


const configDiagnostics = program.getConfigFileParsingDiagnostics();
if (configDiagnostics.size > 0) {
  configDiagnostics.forEach(d =>
    console.error("Config error:", ts.flattenDiagnosticMessageText(d.messageText, "
"))
  );
  course of.exitCode = 1;
} else {
  const diagnostics = ts.getPreEmitDiagnostics(program);
  console.log(diagnostics.size, "errors discovered");
}

import { spawnSync } from "child_process";


const TS_ERROR_PATTERN = /error TSd+:/g;
const MAX_OUTPUT_BYTES = 10 * 1024 * 1024; 

const proc = spawnSync(
  "tsgo",
  ["--noEmit", "--pretty", "false"],   
  {
    encoding: "utf-8",
    maxBuffer: MAX_OUTPUT_BYTES,
    shell: false,                       
  }
);

if (proc.error) {
  throw new Error(`Did not spawn tsgo: ${proc.error.message}`);
}


const output = (proc.stdout ?? "") + (proc.stderr ?? "");
const errorCount = (output.match(TS_ERROR_PATTERN) ?? []).size;
console.log(errorCount, "errors discovered");


if (proc.standing !== 0 && errorCount === 0) {
  console.error("tsgo exited with standing", proc.standing, "— potential compiler crash");
  course of.exitCode = proc.standing ?? 1;
}

Confirm that tsgo helps the --pretty false flag by checking tsgo --help. stdout and stderr are captured individually to keep away from conflating compiler diagnostics with runtime errors.

Efficiency Benchmarks: What to Anticipate

Actual-World Construct Time Comparisons

The TypeScript crew printed benchmarks alongside the RC announcement (supply URL and {hardware} specification ought to be confirmed in opposition to the official TypeScript weblog or microsoft/typescript-go repository). The next figures are offered as reported; unbiased verification requires reproducing on matching {hardware}.

Undertaking DimensionTypeScript 5.8TypeScript 7.0 RCSpeedupReminiscence (5.8)Reminiscence (7.0 RC)
Small (~50 recordsdata)2.1s0.4s~5x180 MB85 MB
Medium (~500 recordsdata)11.8s1.4s~8x620 MB210 MB
Giant monorepo (~5,000+ recordsdata)68s7.2s~9.4x2.8 GB890 MB

Observe: In contrast in opposition to TypeScript 5.8, the newest steady model at time of measurement. Benchmark outcomes range with {hardware}, OS, Node.js model, and challenge construction.

Watch mode responsiveness additionally improves: chilly begin for tsgo --watch is beneath 200ms in comparison with over 1 second for tsc --watch on the identical {hardware} (actual figures rely upon machine specs). Incremental rebuilds after single-file modifications drop to near-instant in small and medium initiatives.

Migration Guidelines

Part 1: Evaluation

Part 2: Set up and Configuration

  • Set up TypeScript 7.0 RC alongside current model, pinned to a particular model
  • Delete stale .tsbuildinfo recordsdata earlier than the primary tsgo run
  • Run tsgo --noEmit in opposition to challenge and evaluate diagnostic output with tsc
  • Replace tsconfig.json for eliminated choices (preserveConstEnums) and unported options (declarationMap)

Part 3: Construct Pipeline and Tooling

  • Regulate construct scripts and CI/CD pipelines to make use of tsgo
  • Cache native binary in CI and guarantee OS/structure match
  • Replace VS Code settings for native language service (confirm setting key in opposition to extension documentation)
  • Validate all programmatic API utilization and migrate to subprocess invocation or retain JS compiler for these paths

Part 4: Validation and Rollout

  • Run full take a look at suite and evaluate outcomes between each compilers
  • Benchmark construct occasions with --diagnostics and doc enhancements
  • Arrange parallel compiler runs in CI for validation interval
  • Plan timeline for dropping legacy tsc dependency after steady launch

Ought to You Migrate Now?

When to Undertake the RC At this time

Groups whose CI type-check exceeds roughly 10 seconds (round 500+ recordsdata) stand to achieve probably the most. A 9x enchancment on a 68-second construct interprets straight into sooner suggestions loops.

Greenfield initiatives with no Compiler API dependencies face the fewest migration dangers. Groups already comfy operating RC software program in improvement, with the JavaScript compiler as a fallback in manufacturing CI, can start extracting worth instantly. Don’t use the RC compiler to gate manufacturing releases and not using a parallel tsc security web.

Groups whose CI type-check exceeds roughly 10 seconds (round 500+ recordsdata) stand to achieve probably the most. A 9x enchancment on a 68-second construct interprets straight into sooner suggestions loops.

When to Await Secure

  • Your challenge will depend on the TypeScript Compiler API for code era, customized lint guidelines, or AST transformers, and desires that API to work in opposition to the identical compiler binary.
  • You employ --build mode for complicated multi-project workspaces and can’t tolerate orchestration gaps.
  • Your setting is risk-averse, and a compiler behavioral divergence may trigger manufacturing points. Await the steady launch, when the divergence challenge tracker reveals decision of identified variations.

Abstract and Subsequent Steps

Migrating from the JavaScript-based TypeScript compiler to the Go-based tsgo requires fewer than 5 configuration modifications for initiatives that use TypeScript for type-checking and emit with out counting on the programmatic API. Confirm the present bundle title on the typescript-go releases web page, set up it, run tsgo alongside tsc, evaluate diagnostics, replace configurations, and regulate construct pipelines. The programmatic API hole is probably the most important blocker for tool-heavy initiatives.

The official TypeScript 7.0 RC launch notes and migration documentation can be found on the TypeScript weblog and the microsoft/typescript-go GitHub repository. Check in non-production environments and report divergences by way of the repository’s challenge tracker to assist the crew attain a steady launch.


Related Articles

Latest Articles