I tested the migration from TypeScript 6.0.3 to 7.0.2 in two Node services. Both passed type-checking, builds, and Docker image builds without changing a line of code. Another workspace in the same monorepo intentionally remained on TypeScript 6 because its checker still imports the previous API. That difference captures the safest way to adopt TypeScript 7 today.
TypeScript 7 is not a typical language update. Microsoft ported the compiler and language server to Go so type analysis can run as native code, use multiple CPU cores, and scale better on large projects.
The goal was not to redesign the type system. The native compiler preserves the structure and logic of the previous implementation to keep results consistent with TypeScript 6, while changing how the work is executed.
That distinction matters. For many Node services, migration can be as small as updating one dependency. Frameworks and tools that import TypeScript inside their own compilers or language servers still need more time.
What Actually Changed
Through TypeScript 6, tsc was an application written in TypeScript and executed by Node.js. TypeScript 7 installs a native executable built from the Go port.
The port preserves the compiler's logic while changing its execution foundation and enabling parallel work.
The main result is performance:
| Project | TypeScript 6 | TypeScript 7 | Speedup |
|---|---|---|---|
| VS Code | 125.7 s | 10.6 s | 11.9× |
| Sentry | 139.8 s | 15.7 s | 8.9× |
| Playwright | 12.8 s | 1.47 s | 8.7× |
| tldraw | 11.2 s | 1.46 s | 7.7× |
Official results show speedups between 7.7× and 11.9× on full builds.
These figures come from the TypeScript team. Their tests also report memory reductions between 6% and 26% across those projects.
The improvement affects more than CI builds:
- Initial project loading in the editor.
- Diagnostics while typing.
- Autocomplete.
- Find all references.
tsc --watch.- Builds using project references.
The native compiler can parallelize parsing, type-checking, and emit. TypeScript 7 uses four type-checker workers by default and exposes the experimental --checkers flag to adjust that number.
The Important Limitation: TypeScript 7 Does Not Have a Public API Yet
TypeScript 7.0 includes the CLI, compiler, and an LSP-based language server, but it does not yet expose a stable programmatic API.
That affects tools that do more than invoke tsc. Some frameworks import TypeScript to analyze code inside their own compilers and language services.
The official announcement calls out these ecosystems directly:
- Astro.
- Vue.
- Svelte.
- MDX.
- Angular template analysis.
- Tools such as
typescript-eslint.
One current example is @astrojs/check 0.9.9, which still declares this peer dependency:
{
"typescript": "^5.0.0 || ^6.0.0"
}Forcing TypeScript 7 into that workspace just to use the latest version adds no value. It can break the checker or create a package combination its maintainers do not support.
A monorepo can therefore look like this during the transition:
Node service A TypeScript 7.0.2
Node service B TypeScript 7.0.2
Workspace with embedded checker TypeScript 6.0.3A monorepo does not need one compiler version across every package. Each workspace can declare the version supported by its own toolchain.
Migration depends on how each tool consumes TypeScript, not on keeping one version number across the repository.
Migrating a Node Service to TypeScript 7
Consider a Node service with this configuration:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2022"],
"outDir": "dist",
"rootDir": "src",
"strict": true,
"noUncheckedIndexedAccess": true,
"resolveJsonModule": true,
"types": ["node"]
},
"include": ["src/**/*"],
"exclude": ["dist", "node_modules"]
}This configuration already avoids two of the most surprising TypeScript 7 defaults:
rootDiris explicit.- Required global type packages are listed in
types.
TypeScript 7 adopts the defaults introduced by TypeScript 6. Among them, strict becomes true, the default rootDir changes, and types defaults to [].
An explicit tsconfig.json prevents a project from depending on defaults that may change between releases.
With pnpm, the update can be scoped to one workspace:
pnpm --filter api add -D typescript@7.0.2For a standalone npm project:
npm install --save-dev --save-exact typescript@7.0.2Then validate the real delivery path, not only tsc --version:
pnpm check
pnpm build
docker compose build apiIn the real migration, both services compiled without changing a line of TypeScript. They already used TypeScript 6 and explicitly configured strict, rootDir, types, and NodeNext, so the transition was direct.
A Larger Lockfile Does Not Mean the Update Went Wrong
TypeScript 7 distributes native executables for different operating systems and CPU architectures.
After updating an npm project, the lockfile included optional packages with names like these:
@typescript/typescript-darwin-arm64
@typescript/typescript-darwin-x64
@typescript/typescript-linux-arm64
@typescript/typescript-linux-x64
@typescript/typescript-win32-x64That does not mean npm installs every binary in production. They are optional dependencies, and the package manager selects the one matching the current platform.
The lockfile change is visible and expected. Knowing that beforehand avoids mistaking a larger diff for an accidental dependency update.
TypeScript 6 and 7 Can Run Side by Side
Microsoft published @typescript/typescript6 for tools that still require the previous API.
An application can keep TypeScript 6 under the typescript name and install the native compiler under a separate alias:
{
"devDependencies": {
"@typescript/native": "npm:typescript@7.0.2",
"typescript": "npm:@typescript/typescript6@6.0.2"
}
}With this combination:
npx tscruns TypeScript 7.tsc6remains available for comparison.- Tools that import
typescriptcontinue to receive the TypeScript 6 API.
Aliases are not always necessary. In a monorepo with independent packages, keeping TypeScript 7 in Node services and TypeScript 6 in workspaces that still need the API is often simpler.
Controlling Parallelism in CI
TypeScript 7 uses four type-checker workers by default. --checkers and --builders are experimental controls, so measure them before adding them to a stable CI script.
On a machine with several CPU cores, you can experiment with:
tsc --checkers 8On a small runner or one with limited memory, the opposite may work better:
tsc --checkers 1There is also a fully sequential mode:
tsc --singleThreadedFor monorepos using project references, --builders controls how many projects may build in parallel:
tsc --build --builders 2 --checkers 2Treat both values carefully. --builders 4 --checkers 4 can allow up to sixteen type-checkers to run at once.
My initial recommendation is to keep the defaults. Adjust them only after measuring CPU, memory, and total build time on the actual runner.
If You Are on TypeScript 5, Do Not Jump Directly to 7
TypeScript 7 turns several options deprecated in TypeScript 6 into hard errors.
Some of the most important removals are:
target: "es5"is no longer supported.moduleResolution: "node"and"node10"are no longer supported.moduleResolution: "classic"was removed.module: "amd","umd","systemjs", and"none"were removed.baseUrlis no longer supported.esModuleInteropcannot be set tofalse.allowSyntheticDefaultImportscannot be set tofalse.
The safer path is:
TypeScript 5
↓
TypeScript 6
↓ fix deprecations and configuration
TypeScript 7A project that compiles cleanly with TypeScript 6, enables stableTypeOrdering, and does not hide deprecation warnings should produce equivalent results with TypeScript 7.
Migration Checklist
Before updating:
- Move to TypeScript 6 first.
- Remove deprecated flags.
- Declare
rootDir. - List required packages in
types. - Review plugins that import the TypeScript API.
After updating:
- Run
tsc --noEmit. - Run the real build.
- Run the tests.
- Build the Docker image.
- Review the lockfile growth.
- Test the editor and
--watch. - Measure before changing
--checkersor--builders.
Conclusion
TypeScript 7 starts a new era for the project. The biggest change is not new syntax, but moving the compiler away from a single-threaded JavaScript application.
For modern Node services, migration can be surprisingly calm. In two real projects, updating from 6.0.3 to 7.0.2 and running the usual gates—type-checking, build, and Docker—was enough.
The important part is not turning the upgrade into a race to standardize every workspace on one version. Astro and other embedded-language tools still need TypeScript 6 because TypeScript 7.0 does not expose the API they use.
The best strategy today is hybrid: TypeScript 7 where the CLI is enough, TypeScript 6 where the toolchain still needs it, and another compatibility review when TypeScript 7.1 publishes the programmatic API.