Finished reading? Continue your journey in Dev with these hand-picked guides and tutorials.
Boost your workflow with our browser-based tools
Share your expertise with our readers. TrueSolvers accepts in-depth, independently researched articles on technology, AI, and software development from qualified contributors.
TrueSolvers is an independent technology publisher with a professional editorial team. Every article is independently researched, sourced from primary documentation, and cross-checked before publication.
TypeScript 6.0 landed on March 23, 2026 as the final release built on the original JavaScript compiler, and it changed nine default compiler settings simultaneously. Which ones break your build depends almost entirely on how your tsconfig was written. The good news: one of those changes already delivers a meaningful performance improvement without waiting for TypeScript 7.0. The harder news: the path to 7.0 has a tooling compatibility trap that most migration guides skip.

This guide covers what changed, which changes are safe to defer, what the 10x speed promise actually means for your project size, and what to do before TypeScript 7.0 ships.
The Microsoft TypeScript DevBlog documents TypeScript 6.0's release on March 23, 2026, authored by Principal Product Manager Daniel Rosenwasser. The release is API-compatible with TypeScript 5.9, meaning the language itself behaves identically: what changed is what TypeScript assumes when you do not tell it otherwise.
The nine defaults that shifted: strict is now true, module defaults to esnext, target to es2025, moduleResolution to bundler, esModuleInterop to true, types to an empty array, rootDir to . (the directory containing your tsconfig), noUncheckedSideEffectImports to true, and libReplacement to false. Most of these will already match what well-maintained projects explicitly set. Two will not.
The types field is the one most likely to detonate on upgrade. Previously, TypeScript silently crawled every package under node_modules/@types and included all of them in every build. Setting this to an empty array means TypeScript no longer auto-discovers @types/node, @types/jest, or any other globals. Developers who did not explicitly list these will see a wave of errors for identifiers like process, Buffer, and describe the moment they install TypeScript 6.0.
The TypeScript 6.0 release notes specify that the types field defaulting to [] has produced 20-50% build time improvements in Microsoft's tested projects. The reason is architectural: when TypeScript no longer needs to include hundreds of transitive @types packages in every build, the scope of what it must analyze shrinks considerably. This is not a trivial cleanup; in large monorepos, the reduction in loaded declaration files has a compounding effect on both compile time and watch-mode responsiveness.
The rootDir change catches a different class of project. Previously, TypeScript inferred the common source directory from the set of input files. A project with all source files under src/ would automatically use src/ as the root, so output landed in dist/index.js. In TypeScript 6.0, rootDir defaults to the directory containing tsconfig.json, not the computed source root. A project sitting at the root of a repository with source under src/ will now emit to dist/src/index.js unless rootDir is set explicitly. TypeScript does not silently produce wrong output; it emits an error pointing to exactly what to set. But teams running automated builds will see CI fail the first time they upgrade without fixing this first.
Projects that already have strict: true, explicit types, and explicit rootDir will find the upgrade mostly mechanical. The dangerous upgrades are the ones that relied on TypeScript's inferences, and those projects are more common than documentation would suggest.
The types: [] change is simultaneously the most breaking change on upgrade for projects that relied on auto-discovery and the most immediate performance gain available without waiting for TypeScript 7.0. Fixing it is not optional, but doing so properly also starts delivering value before the Go compiler ships.
TypeScript 7.0 is a complete rewrite of the compiler and language service in Go, codenamed Project Corsa internally. The original JavaScript-based compiler is codenamed Strada. The Go compiler ships as tsgo, a binary that accepts the same flags as tsc and reads existing tsconfig.json files without modification.
The headline performance figure is accurate at a specific scale. PkgPulse's benchmarks, run on the TypeScript compiler's own repository at approximately 400,000 lines on Apple M1 Pro hardware, measured tsc at 0.284 seconds total with type-checking at 0.103 seconds, against tsgo at 0.026 seconds total with type-checking at 0.003 seconds. That is a 10.8x overall improvement and approximately 30x faster type-checking, with memory usage dropping from 68 megabytes to 23 megabytes. Real-world large projects show similar numbers: developer-tech.com documented the Sentry codebase dropping from 133 seconds to 16 seconds with tsgo. The Microsoft TypeScript DevBlog documented the VS Code codebase (1.5 million lines) dropping from 77.8 seconds to 7.5 seconds with a full type-check.
The gains do not distribute evenly across project sizes. Projects under 10,000 lines see approximately 4x improvement. Projects between 10,000 and 100,000 lines see roughly 6x. The range from 100,000 to 500,000 lines lands around 8.8x. Only projects above 500,000 lines consistently reach the 10x figure. For most individual applications, 4-6x is the realistic baseline. That is still substantial: a 5-second type-check becoming 1 second changes how often developers run it. But teams should calibrate expectations against their actual codebase size, not the monorepo headlines.
The improvement comes primarily from parallelism, not simply from compiling Go vs. interpreting JavaScript. The current compiler runs single-threaded on Node.js, meaning the V8 garbage collector pauses during long type-checking runs and the entire type graph must be processed sequentially. The Go compiler uses shared-memory goroutines to parallelize type-checking across files within a project, and it can build multiple projects in a reference graph simultaneously. Type-checking is CPU-bound work, which makes it a near-ideal candidate for this kind of parallel decomposition.
Anders Hejlsberg's original announcement of the Go rewrite documented that editor project load time dropped from 9.6 seconds to 1.2 seconds in the VS Code scenario, and that overall memory usage is roughly half the current implementation. The performance gains extend beyond CI: they change the IDE experience from the moment a developer opens a large project.
The VS Code codebase drops from 77.8 seconds to 7.5 seconds with tsgo, but on projects under 100,000 lines, the same compiler delivers 4-6x gains, not 10x, and the types: [] default Microsoft introduced in 6.0 already closes a meaningful fraction of that gap before 7.0 ships. A project currently taking 30 seconds to type-check will likely reach 5 seconds with tsgo. That same project may be down to 20-24 seconds already from the types scoping change alone. The conclusion from the combined data is that 6.0's configuration changes are not just migration prerequisites; they are the first tranche of the performance dividend.
We cannot confirm the precise stable release window for TypeScript 7.0. Microsoft's official position is that it expects a release "within a few months" of TypeScript 6.0's March 2026 launch, but at least one practitioner analysis suggests the stable, fully production-ready release may arrive in late 2026 or early 2027 depending on how quickly the remaining API work completes. The preview is available today and type-checking is production-safe; emit is not yet complete.
The configuration changes dominate the conversation around TypeScript 6.0, but the release also includes genuine language-side additions. None change how TypeScript's type system works at a fundamental level, but several close long-standing gaps with the JavaScript standard library.
The Announcing TypeScript 6.0 release notes specify that Temporal reached Stage 4 and is now part of the standard library target. For years, JavaScript's Date object has been notorious for inconsistent timezone handling, mutable state, and confusing API design. Temporal provides an immutable alternative with explicit timezone and calendar support. TypeScript 6.0 ships built-in types for Temporal under --target esnext or "lib": ["esnext"], with the more granular esnext.temporal available for teams who want just the Temporal definitions. The catch: the Temporal polyfills (temporal-polyfill and @js-temporal/polyfill) are not interassignable with the 6.0 lib declarations, so projects using those polyfills today will need to check compatibility before relying on the built-in types.
TypeScript 6.0 includes types for two Stage 4 ECMAScript proposals that address common coding patterns. The upsert proposal adds getOrInsert and getOrInsertComputed to Map and WeakMap. The pattern of checking for a key's existence, setting a default if absent, then retrieving the value is ubiquitous in JavaScript. Both methods collapse that three-step pattern into a single call. RegExp.escape handles the equally common problem of constructing a regex from user input: any user-provided string containing characters like *, +, or ( would previously require manual escaping to avoid altering the regex's behavior. The built-in method handles this correctly. Both are available in the es2025 lib, which is now the default target.
A subtle inconsistency between arrow functions and method syntax in generic calls caused inference to fail for methods when the object's property order happened to put a consumer before a producer. TypeScript 6.0 fixes this by treating functions that never reference this as non-contextually-sensitive regardless of syntax. In practical terms, swapping between arrow and method syntax in object literals passed to generic functions no longer causes unexpected type errors. This is a correctness fix rather than a new capability, but it eliminates a class of confusing errors that previously required workarounds.
Node.js recently added support for subpath imports beginning with #/, enabling projects to define internal path aliases without the extra segment that previously required writing #root/ instead of just #/. TypeScript 6.0 supports this under nodenext and bundler module resolution. For developers already using bundler path aliases (@/components/button), the #/ prefix offers a native Node.js equivalent that works without additional configuration.
The dom lib change is smaller but removes friction: dom.iterable and dom.asynciterable are now automatically included when you include dom, eliminating the need to list them separately in the lib array.
The --stableTypeOrdering flag deserves a specific callout. It exists solely for the 6.0-to-7.0 migration window, and it comes with a cost of up to 25% slower type-checking. TypeScript assigns internal IDs to types as it encounters them, and these IDs determine the ordering of union types in output. Because the Go compiler processes types in a non-deterministic order (parallelism makes ordering inherently variable), TypeScript 7.0 uses a deterministic algorithm that does not depend on encounter order. The --stableTypeOrdering flag makes TypeScript 6.0 match that algorithm, so teams can compare .d.ts output between compilers and identify divergences before switching. Do not use this flag for normal development builds: the 25% slowdown makes it unsuitable as a permanent setting.
The deprecations in TypeScript 6.0 share a single organizing principle: each one removes something the Go-based compiler cannot support. Legacy module formats, AMD/UMD targets, classic module resolution, and ES5 output all require special-casing that would need to be ported line-by-line into a codebase designed for shared-memory parallelism. Treating each deprecation warning as merely old-code cleanup misses the architectural signal it carries.
ES5 target and downlevelIteration. TypeScript 6.0 deprecates target: "es5", setting the minimum supported output to ES2015. Internet Explorer's retirement and the near-universal adoption of evergreen browsers makes ES5 output a vanishing requirement. Developers who still need ES5 output — for embedded systems, certain enterprise environments, or legacy CMS integrations — must now route TypeScript output through an external transpiler like Babel or esbuild as a post-processing step. The --downlevelIteration flag is also deprecated, since its only effect was on ES5 emit; setting it at all in TypeScript 6.0 now produces a deprecation error.
Classic and node module resolution. moduleResolution: classic is gone entirely: not deprecated with a warning, but removed. The classic algorithm existed before Node.js developed its own resolution approach and serves no practical purpose in modern projects. moduleResolution: node (which accurately modeled Node.js 10's behavior) is deprecated. The migration target is nodenext for Node.js projects or bundler for any project using Vite, webpack, or a similar build tool.
AMD, UMD, and SystemJS. These module formats are deprecated in 6.0 and will be removed entirely in 7.0. The --outFile option, which concatenated multiple input files into a single output, is gone. Modern bundlers do this job faster, with better tree-shaking, and without TypeScript's involvement. The migration path is to adopt any modern bundler, most of which have first-class TypeScript support.
baseUrl. The baseUrl option is deprecated and no longer acts as a lookup root for module resolution. Most developers who used baseUrl were using it to enable paths mappings, which stopped requiring baseUrl in TypeScript 4.1. The migration is straightforward: remove baseUrl from tsconfig and add the explicit directory prefix to each entry in paths. Teams that used baseUrl as a genuine import root (not just for paths) have a slightly more involved migration but can add an explicit paths entry to preserve the behavior.
All of these deprecated options can be temporarily silenced in TypeScript 6.0 by adding "ignoreDeprecations": "6.0" to tsconfig. This setting suppresses deprecation warnings in 6.0 only. It will not work in TypeScript 7.0, and the deprecated options will be removed entirely when 7.0 ships. Using ignoreDeprecations to defer the migration is a short-term escape valve, not a solution.
The TypeScript 7.0 December 2025 progress update confirms the depth of compatibility between the two compilers: of approximately 20,000 compiler test cases, those producing at least one error in TypeScript 6.0 are matched by TypeScript 7.0 in all but 74 cases. Every one of those 74 discrepancies is documented as either known incomplete work or an intentional change tied to deprecations. The Go compiler is not diverging from the language spec; it is executing the same type system on different infrastructure.
The TypeScript 7.0 December 2025 progress update confirms that the Corsa API is still a work in progress with no stable tooling integration available, meaning the surface area that custom tools, linters, and language service plugins depend on does not yet have a stable replacement.
Most coverage of TypeScript 6.0 and 7.0 focuses on the performance story and the tsconfig changes. The part that affects some teams much more directly is the compiler API transition.
TypeScript's current architecture exposes what Microsoft calls the Strada API: the programmatic interface used by tools like ESLint parsers, ts-loader, custom compiler plugins, language service integrations, and any package that imports typescript as a library rather than running tsc as a binary. The TypeScript 7.0 December 2025 progress update states directly: "Corsa/TypeScript 7.0 will not support the existing Strada API. The Corsa API is still a work in progress, and no stable tooling integration exists for it."
The TypeScript 7.0 December 2025 progress update confirms that the Corsa API is still a work in progress with no stable tooling integration available. This creates a concrete dependency problem: teams cannot complete the tooling side of their TypeScript 7.0 migration independently because the replacement API is not yet stable enough for tool authors to target.
The practical consequence is that any tool in your dependency chain that imports typescript as a library will not function with TypeScript 7.0 until its authors update to the new Corsa API. This includes type-aware ESLint rules (which depend on the TypeScript language service for their analysis), ts-patch and custom transformers, and tools that embed TypeScript's language server for editor functionality outside of VS Code. The InfoQ coverage of TSSLint 3's release flagged this explicitly, noting TSSLint's incompatibility with TypeScript 7's native compiler due to its reliance on Language Service Plugins, which tsgo does not support.
This disruption extends well beyond individual tools. The broader stress on open source maintainer capacity is real: recent research on how AI code generation affects the open source ecosystem documents how the traditional feedback loop connecting users to maintainers is under measurable pressure, which compounds the challenge of coordinating a migration of this scale across hundreds of TypeScript-dependent tools. Tool maintainers who are already managing declining engagement may be slower to ship Corsa API support than the TypeScript team's timeline assumes.
This creates a two-speed migration. Teams that use TypeScript only via the tsc CLI face a largely mechanical transition to TypeScript 7.0 once it ships. Teams running compiler plugins, custom transformers, or type-aware linting face a dependency on third-party tooling authors completing their own Corsa API migrations, on a timeline those teams do not control.
The workaround Microsoft recommends is a parallel installation: keep the standard typescript package installed for any tooling that depends on the Strada API, and add @typescript/native-preview for type-checking performance. This allows CI pipelines to run tsgo --noEmit for fast type validation while still using tsc for everything that depends on the old API. The tsgo preview receives daily updates; pin it to a specific version in CI to avoid surprise regressions.
Library authors face an additional constraint: do not switch the CI type-checking gate from tsc to tsgo until declaration file output has been confirmed identical across multiple runs. TypeScript 7.0's language service uses LSP rather than the tsserver protocol that Strada used, and early preview iterations showed subtle differences in how declaration files were ordered. Switching too early risks publishing declaration files that differ from what consumers building against TypeScript 6.0 produce.
Teams running compiler plugins, ts-patch, custom transformers, or ESLint rules that depend on the TypeScript language service API face a more complicated transition than the official documentation communicates. The Strada API will not be ported to TypeScript 7.0, meaning those tools require either the parallel-install workaround or a dependency on the new Corsa API that is still under active development. Based on current information from the TypeScript 7.0 December 2025 progress update, which acknowledged this gap, how long the two-compiler period lasts depends on how quickly the Corsa API stabilizes and how quickly tool authors update their integrations: a timeline no team can control unilaterally.
The TypeScript 6.0 migration has two distinct phases, and conflating them creates problems in both directions. Phase one is the tsconfig work that must happen regardless of 7.0's timeline. Phase two is the tooling API migration for 7.0, which teams cannot complete unilaterally. Treating the phases as one task creates false urgency on the second and false comfort on the first.
Phase one: get to 6.0 with no deprecation warnings.
Start with the ts5to6 migration tool by Andrew Branch, a TypeScript team member, which automates the baseUrl removal and rootDir inference correction. Run it before installing TypeScript 6.0:
npx @andrewbranch/ts5to6 --fixBaseUrl .
npx @andrewbranch/ts5to6 --fixRootDir .
Then install TypeScript 6.0 and run a type-check with --noEmit:
npm install -D typescript
npx tsc --noEmit
Add an explicit types array to compilerOptions. At minimum, include "node" for Node.js projects and any test framework types your project uses ("jest", "mocha", etc.). This single change is both the most likely source of errors on upgrade and the most immediate build time improvement available.
Decide how to handle strict: true. Projects that ran without strict mode will see new errors. The options are to address them now (the correct long-term path), or temporarily set "strict": false explicitly to preserve previous behavior while scheduling the strict mode work separately. Do not use ignoreDeprecations: "6.0" as a permanent solution: it defers the deprecation work without eliminating it, and it will not carry forward to 7.0.
TypeScript 6.0 also changes the behavior of running tsc with a specific file name when a tsconfig.json exists in the same directory. Previously, the tsconfig was silently ignored. In TypeScript 6.0, this combination produces an error. If your build scripts or CI commands invoke tsc with explicit file arguments, add the --ignoreConfig flag to preserve the prior behavior.
Phase two: start testing tsgo in parallel.
Once your project is clean on TypeScript 6.0 with no deprecation warnings, install the native preview alongside your existing compiler:
npm install -D @typescript/native-preview
This provides a tsgo command. Add a non-blocking CI job that runs npx tsgo --noEmit and compares its output to tsc --noEmit. When the outputs are consistently identical across your codebase, you can switch the CI gate to tsgo for type-checking, keeping tsc for anything that depends on the Strada API. The @typescript/native-preview package receives daily updates; if you use it in CI, pin it to a specific version and update deliberately.
If your project depends on compiler plugins, ts-patch, or type-aware ESLint rules, the phase two transition requires waiting for those tools to ship Corsa API compatibility before tsgo can fully replace tsc. Track the microsoft/typescript-go repository and your specific tool maintainers' issue trackers for API readiness signals.
The migration tooling for TypeScript 6.0 is mature. Getting to 6.0 with zero deprecation warnings and an explicit types array is achievable in a single sprint for most projects. That work is the prerequisite for everything that follows.
Library authors carry a different risk profile than application developers. Their compiled output, specifically the .d.ts declaration files, is consumed by downstream packages that may be running a range of TypeScript versions. Switching to tsgo for declaration file generation before the output is confirmed identical to tsc's output risks publishing declaration files that differ in type ordering or structure from what TypeScript 6.0 consumers expect.
The safest approach for library authors is to complete the TypeScript 6.0 tsconfig migration first, publish a release that validates cleanly under 6.0, and then run tsgo --noEmit as a parallel CI check. Do not switch declaration file generation to tsgo until you have confirmed across multiple builds that declaration file output is byte-for-byte identical. The Corsa API's incomplete state also means any tooling that post-processes declaration files may need updates before library authors can safely adopt tsgo for emit.
Library authors using isolatedDeclarations can benefit from TypeScript 6.0 directly: the feature stabilizes in 6.0 and enables faster parallel declaration file generation using the existing JavaScript compiler, before tsgo's emit is production-ready.
Framework CLIs manage tsconfig files differently. Next.js, for example, generates and extends its own tsconfig.json with framework-specific defaults. In many cases, framework-managed configurations will not immediately surface all nine default changes because the framework's extended config sets explicit values.
The safest approach is to check your framework's compatibility matrix for TypeScript 6.0 before upgrading. Run npx tsc --noEmit after upgrading to see what errors surface in your specific project. For Next.js projects, the App Router's configuration is managed separately from the application tsconfig, and framework-level TypeScript support typically follows TypeScript releases within a few weeks. For Angular projects, check the Angular compatibility matrix directly, as Angular pins to specific TypeScript ranges.
Even in framework projects, the types field is worth auditing explicitly. Framework CLIs may not set this field, meaning TypeScript 6.0's empty default could surface errors in framework-generated code that depends on globally available type packages.
TypeScript 6.0 deprecates target: "es5" and sets ES2015 as the minimum supported output target. The deprecation produces a warning in TypeScript 6.0; the option will be removed entirely in TypeScript 7.0.
For teams with genuine ES5 requirements, the migration path is to let TypeScript emit ES2015 output and then route that output through an external transpiler like Babel or esbuild as a post-processing step. Both tools support TypeScript input and ES5 output. esbuild is significantly faster; Babel has a more mature plugin ecosystem for edge cases. This two-step approach decouples TypeScript's type-checking from the downleveling step, which is architecturally cleaner and often results in smaller output than TypeScript's own emit.
If your ES5 requirement is specifically for a library targeting very old environments, evaluate whether the actual browser or runtime you target genuinely requires ES5 or whether an ES2015 target has become sufficient. IE11 reached end of life in June 2022, and ES2015 support has been standard in major browsers since 2016.
The TypeScript 7.0 December 2025 progress update confirmed that type-checking with tsgo is production-safe: of the approximately 20,000 compiler test cases, the 74 discrepancies from TypeScript 6.0 are all documented as known incomplete work or intentional changes. For build validation, confirming your codebase has no type errors, tsgo is reliable.
The two areas where tsgo is not yet production-ready are JavaScript emit and the Strada API. If your build pipeline uses tsc for both type-checking and for generating the JavaScript output that gets deployed, you cannot replace tsc entirely with tsgo today. The emit pipeline is still being completed in the native preview. The practical approach is the parallel installation strategy: use tsgo --noEmit for fast CI type-checking, and keep tsc for emit and any tooling that depends on the TypeScript compiler API. This gives you the performance benefit of tsgo's type-checking speed while maintaining production reliability on the emit side.
Pin @typescript/native-preview to a specific version in CI. The package receives daily updates, and an unexpected behavior change in an uncontrolled upgrade can introduce false negatives in your type-checking gate.