Back to Blog
Full Stack

Migrating to TypeScript 7: A Practical Guide to the Native Go Compiler

TypeScript 7 rewrites the compiler in Go for roughly 10x faster builds. Here's a step-by-step migration covering removed options, new defaults, and the missing API caveat.

Sanjay ThakurSeptember 29, 20266 min read
Migrating to TypeScript 7: A Practical Guide to the Native Go Compiler

TypeScript 7.0 is the release where the compiler stopped being written in TypeScript. The team ported it to Go, and the result is a compiler and language service that are roughly ten times faster on real codebases. A couple of months after launch, it's now a realistic upgrade for most React and Node.js projects, but it isn't a drop-in version bump. Old options were removed, several defaults changed, and there's one big caveat around tooling. Here's how I'd approach the migration.

What You Actually Get

The headline is speed. Microsoft's announcement reports full type-check speedups of 11.9x on the VS Code codebase, and around 8.7x to 8.9x on projects like Sentry, Bluesky, and Playwright, with memory usage down by 6–26%. Opening a file in the editor on the VS Code codebase went from about 17.5 seconds to 1.3 seconds.

In practice, that means:

  • CI type-check steps that used to dominate a pipeline become a rounding error.
  • Editor features like go-to-definition and error squiggles feel instant, even in large monorepos.
  • The language server is built on the Language Server Protocol, with the team reporting far fewer crashes and failing commands.

Step 1: Get to TypeScript 6.0 First

The official recommendation is to adopt TypeScript 6.0 before 7.0. The 6.0 release acts as a bridge: it deprecates the options 7.0 removes, so fixing its warnings is the cheapest way to find what will break.

npm install -D typescript@6
npx tsc --noEmit

Fix every deprecation warning before moving on.

Step 2: Remove Options That No Longer Exist

TypeScript 7 drops support for a list of legacy settings. The ones most likely to appear in older projects:

  • target: "es5" and downlevelIteration
  • moduleResolution: "node" / "node10" / "classic"
  • module: "amd", "umd", "systemjs", "none"
  • baseUrl
  • esModuleInterop: false and allowSyntheticDefaultImports: false

baseUrl is the one that bites most teams, because path aliases often depend on it. Make your paths entries relative to the tsconfig.json instead:

{
  "compilerOptions": {
    "target": "es2022",
    "module": "esnext",
    "moduleResolution": "bundler",
    "strict": true,
    "types": ["node"],
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"]
}

Step 3: Account for New Defaults

Several defaults changed. If you relied on the old behavior implicitly, set it explicitly or adapt your code:

  • strict now defaults to true.
  • module defaults to esnext.
  • noUncheckedSideEffectImports defaults to true, so a side-effect import such as import "./polyfills" that can't be resolved is now an error.
  • types defaults to [], so global type packages like @types/node or test-runner globals are no longer picked up automatically. List them in types.
  • rootDir defaults to the directory containing tsconfig.json; adjust it if your config lives outside your source folder.

The types change is the one that generates the most confusing errors ("Cannot find name 'process'" or "Cannot find name 'describe'"). If you see those, add the missing entries:

{
  "compilerOptions": {
    "types": ["node", "vitest/globals"]
  }
}

Step 4: Upgrade and Measure

npm install -D typescript@7
time npx tsc --noEmit

TypeScript 7 also adds flags for tuning its parallelism. --checkers and --builders control how much work runs in parallel, and --singleThreaded is useful for debugging or on constrained CI runners:

# Useful on small CI machines or when chasing a nondeterministic error
npx tsc --noEmit --singleThreaded

The Big Caveat: No API Yet

TypeScript 7.0 does not ship a programmatic API; the team expects that to stabilize in 7.1. Anything that imports the typescript package as a library, such as some lint rules that need type information, framework language tools, or custom codegen scripts, may still need the 6.0 API.

The TypeScript team documents a side-by-side setup for this: keep the 6.0 package available under the typescript name for tools, and install 7.0 under an alias for type-checking.

{
  "devDependencies": {
    "@typescript/native": "npm:typescript@^7.0.2",
    "typescript": "npm:@typescript/typescript6@^6.0.2"
  }
}

Framework users should read this caveat carefully: the announcement advises Vue, Angular, Svelte, and Astro projects to stay on TypeScript 6.0 until the API is stable. For a plain React, Next.js, or Node.js codebase, the path is usually clear once your lint setup is checked.

A Migration Checklist

  1. Upgrade to TypeScript 6.0 and fix all deprecation warnings.
  2. Remove baseUrl and other dropped options; rewrite paths relative to the config.
  3. Set types explicitly and confirm strict and rootDir behave as expected.
  4. Check lint rules, codegen, and framework tooling for dependencies on the compiler API.
  5. Upgrade to 7.0 on a branch, run the full type-check, and compare CI times.

Key Takeaways

  • TypeScript 7 is a Go port of the compiler with roughly 10x faster builds and a much faster editor experience.
  • Move to 6.0 first; its deprecations are your migration to-do list.
  • Legacy options like baseUrl, target: "es5", and moduleResolution: "node" are gone.
  • New defaults (strict, types: [], noUncheckedSideEffectImports) cause most post-upgrade errors.
  • There is no compiler API in 7.0; tools that need one can use the documented side-by-side 6.0 setup until 7.1.

Resources

TypeScriptToolingPerformanceNode.js