TypeScript 6.0 Released: Every Breaking Change You Need to Know
TypeScript 6.0 marks the final JavaScript-based release with strict defaults, ES5 removal, and breaking tsconfig changes. Here's what breaks and how to fix it.
Most TypeScript upgrade problems stem from defaults changing beneath teams who never explicitly configured their build. TypeScript 6.0 shipped in March 2026 as the last JavaScript-based compiler release, and it removes patterns that survived deprecation warnings through multiple 5.x releases. Strict mode is now default. ES5 support is gone. Several tsconfig fields changed their implicit values. The failure mode here is subtle but expensive: builds that passed in 5.9 will fail in 6.0, not because your code is wrong, but because the compiler now enforces what it previously warned about.
This matters because TypeScript 6.0 represents a deliberate breaking point. The team signaled that future releases will move to a new runtime foundation, and 6.0 clears legacy debt before that transition. Teams running on 5.x without explicit configuration will see immediate breaks. Teams who ignored deprecation warnings will see compilation failures. The implication here is that you cannot treat this as a minor version bump.
Key Takeaways
- TypeScript 6.0 enables strict mode by default, breaking codebases that relied on loose checking
- ES5 target support is removed entirely; the minimum target is now ES2015
- Several tsconfig.json defaults changed, including
moduleResolutionandskipLibCheck - The
--ts6-migrationflag automates detection of removed features and suggests fixes - Performance improved 15-30% for large codebases due to internal optimizations in type checking
Breaking Changes in tsconfig.json Defaults
The most immediate breaks come from tsconfig.json defaults that flipped without warning. In TypeScript 5.x, strict defaulted to false. In 6.0, it defaults to true. That single change enables eight compiler flags: noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, alwaysStrict, and useUnknownInCatchVariables.
The other critical default is moduleResolution. In 5.x, omitting this field meant node resolution. In 6.0, the default is node16, which treats .js extensions literally and enforces package.json exports fields. This breaks imports that worked under loose resolution.
%% alt: TypeScript 6.0 tsconfig.json default changes flow
flowchart TD
Start[Upgrade to TypeScript 6.0]
Start --> Check{Explicit tsconfig?}
Check -->|No| NewDefaults[New defaults applied]
Check -->|Yes| OldBehavior[Behavior preserved]
NewDefaults --> Strict[strict: true]
NewDefaults --> ModRes[moduleResolution: node16]
Strict --> Breaks1[Implicit any errors]
ModRes --> Breaks2[Import resolution failures]
Breaks1 --> Fix[Add explicit types]
Breaks2 --> FixImports[Fix import extensions]
classDef framework fill:#142544,stroke:#7c9cf0,color:#eaf2ff
classDef userAction fill:#0b3b2e,stroke:#34d399,color:#d1fae5
class Start,Fix,FixImports userAction
class NewDefaults,Strict,ModRes framework
The other silent change: skipLibCheck now defaults to false. Most teams set this to true to avoid type-checking node_modules, but in 6.0 the compiler will check all .d.ts files unless you explicitly opt out. This exposes type errors in dependencies that you cannot fix directly.

The fix is straightforward but tedious: explicitly set every field you relied on. If your build worked in 5.9 with no tsconfig.json, create one and lock in 5.x behavior. If you had a minimal tsconfig.json, expand it. The alternative is fixing hundreds of type errors that appear overnight.
Removed and Deprecated Features You Must Address
TypeScript 6.0 removes three features that were marked deprecated in 5.x: prepend projects, out compilation, and namespace module augmentation patterns. The first two rarely matter in modern codebases. The third breaks a specific pattern where teams augmented namespaces across module boundaries.
The more impactful removal is --target es5. Teams still compiling to ES5 for Internet Explorer 11 support must now compile to ES2015 and transpile down with a separate tool. The TypeScript compiler no longer generates ES5 output. This distinction is critical: you can still run TypeScript 6.0 on Node 18+, but you cannot target ES5.
// This worked in TypeScript 5.x
namespace MyLib {
export interface Config {
apiKey: string;
}
}
// In another file, augmenting the namespace
namespace MyLib {
export interface Config {
timeout?: number; // ERROR in TypeScript 6.0
}
}
// The correct pattern in 6.0: use interface merging
export interface MyLibConfig {
apiKey: string;
}
// In another file
export interface MyLibConfig {
timeout?: number; // Works correctly
}The namespace pattern fails because the compiler now enforces module boundaries more strictly. Interface merging works because it follows the module system's rules. The failure mode here is that code compiles with warnings in 5.9 but fails outright in 6.0.
The other breaking removal: --keyofStringsOnly. This flag made keyof return only string keys, ignoring symbol and number keys. It was deprecated in 5.4 and removed in 6.0. If your codebase relied on this, you will see type errors where keyof T now includes symbol keys.
The New Migration Flag: --ts6-migration Explained
TypeScript 6.0 introduces --ts6-migration, a compiler flag that runs your codebase through a static analysis pass and reports patterns that will break. This flag does not run the type checker; it scans for syntax and configuration patterns that 6.0 removed.
Running tsc --ts6-migration generates a report listing every file that uses a removed feature. The output includes line numbers and suggested fixes. The tool catches namespace augmentation, ES5-specific syntax, and deprecated compiler options. It does not catch runtime breaks or behavior changes, only static patterns.
%% alt: TypeScript 6.0 migration flag execution flow
flowchart TD
Run[Run tsc --ts6-migration]
Run --> Scan[Scan codebase for removed patterns]
Scan --> Report[Generate migration report]
Report --> Check{Issues found?}
Check -->|Yes| Fix[Apply suggested fixes]
Check -->|No| Upgrade[Safe to upgrade]
Fix --> Rerun[Re-run migration check]
Rerun --> Check
Upgrade --> Done[Upgrade to TypeScript 6.0]
classDef userAction fill:#142544,stroke:#7c9cf0,color:#eaf2ff
classDef framework fill:#0b3b2e,stroke:#34d399,color:#d1fae5
class Run,Fix,Upgrade userAction
class Scan,Report,Rerun framework
The implication here is that you can safely run this flag on 5.9 before upgrading. It will not change your build output or type-check results. It only reports what will break. Teams should run this on CI and treat the report as a blocker for the 6.0 upgrade.
The migration flag does not detect strict mode errors. Those only surface when you run the full type checker. The flag also does not detect moduleResolution mismatches. You must test those manually by running a build with the new defaults.
ES5 Support Dropped: What This Means for Legacy Targets
Removing ES5 support means the TypeScript compiler no longer emits var, function declarations for classes, or ES3-compatible output. The minimum target is ES2015, which assumes let, const, arrow functions, classes, template literals, and destructuring. This breaks workflows where teams compiled TypeScript directly to ES5 for legacy browsers.
The workaround is a two-stage build: compile TypeScript to ES2015, then transpile to ES5 with Babel or SWC. This adds a second tool to the build chain but preserves legacy browser support. The tradeoff is complexity: you now manage two configurations instead of one.
%% alt: TypeScript 6.0 ES5 compilation flow comparison
flowchart TD
Legacy[TypeScript 5.x compile to ES5]
Modern[TypeScript 6.0 compile to ES2015]
Legacy --> ES5[ES5 output]
Modern --> ES2015[ES2015 output]
ES2015 --> Transpile[Babel/SWC transpile to ES5]
Transpile --> ES5Final[ES5 output]
style Legacy stroke:#ef4444,fill:#450a0a,color:#fca5a5
classDef framework fill:#142544,stroke:#7c9cf0,color:#eaf2ff
class Modern,Transpile framework
The other consequence: polyfills are now your responsibility. TypeScript 5.x included ES5 polyfills for features like Promise and Map. TypeScript 6.0 assumes those exist in the runtime. If you target ES2015 but run on a browser that lacks Promise support, your code will fail at runtime.
This matters because the compiler will not warn you. It assumes ES2015 support means full ES2015 support. The fix is to use a polyfill library like core-js and explicitly import the features you need.
Strict Mode by Default and How It Affects Existing Code
Strict mode enabled by default is the single largest source of migration pain. Codebases that never configured strict will suddenly see hundreds of type errors. The most common errors: implicit any in function parameters, null checks missing on optional properties, and incorrect this types in callbacks.
The pattern that breaks most often: functions that accept parameters without type annotations. In non-strict mode, these defaulted to any. In strict mode, the compiler requires explicit types. This affects event handlers, callback functions, and utility helpers.
// This compiled in TypeScript 5.x (non-strict)
function handleClick(event) {
console.log(event.target.value); // event is implicitly any
}
// In TypeScript 6.0 strict mode, this fails
function handleClick(event) { // ERROR: Parameter 'event' implicitly has an 'any' type
console.log(event.target.value);
}
// The correct pattern: explicit types
function handleClick(event: React.MouseEvent<HTMLButtonElement>) {
console.log(event.currentTarget.value);
}The other strict mode break: null checks on optional properties. In non-strict mode, accessing obj.property?.field did not require null checks. In strict mode, the compiler tracks nullability through the entire chain. If field is optional, accessing it requires a check or non-null assertion.

The pragmatic fix: enable strict mode incrementally. Add strict: true to tsconfig.json and fix errors file by file. The compiler's error output shows which files break. You can exclude files temporarily and address them over weeks instead of days.
Performance Improvements and Internal Changes
TypeScript 6.0 improves type-checking performance by 15-30% for large codebases through internal optimizations in how the compiler caches resolved types. The team rewrote the type cache to use a more efficient data structure, reducing memory allocations during recursive type resolution. This matters for codebases with deep union types or complex conditional types.
The other performance win: faster incremental builds. The compiler now tracks file dependencies more accurately, avoiding unnecessary re-checks when unrelated files change. Teams see the biggest improvement in monorepos where a single file change previously triggered full project rebuilds.
%% alt: TypeScript 6.0 type checking performance comparison
flowchart LR
subgraph TypeScript5["TypeScript 5.x: linear cache lookup"]
TS5Start[Type resolution request]
TS5Start --> TS5Cache[Check cache sequentially]
TS5Cache --> TS5Miss{Cache hit?}
TS5Miss -->|No| TS5Compute[Compute type]
end
subgraph TypeScript6["TypeScript 6.0: optimized cache structure"]
TS6Start[Type resolution request]
TS6Start --> TS6Cache[Check hash-indexed cache]
TS6Cache --> TS6Miss{Cache hit?}
TS6Miss -->|No| TS6Compute[Compute type faster]
end
style TS5Compute stroke:#ef4444,fill:#450a0a,color:#fca5a5
classDef framework fill:#142544,stroke:#7c9cf0,color:#eaf2ff
class TS6Cache,TS6Compute framework
The internal change that matters: the compiler now uses a more aggressive caching strategy for module resolution results. In 5.x, the compiler re-resolved imports on every build. In 6.0, it caches resolution results across builds unless package.json or tsconfig.json changes. This shaves seconds off incremental build times in large projects.
The tradeoff is subtle: if you change a dependency's package.json exports without changing its version, TypeScript might not pick up the change until you clear the cache. This rarely happens in practice but explains why some imports resolve incorrectly after dependency updates.
Frequently Asked Questions
Will TypeScript 6.0 break my existing build?
Most builds will break unless you have explicit tsconfig.json settings for strict, moduleResolution, and target. The compiler changed defaults for all three, and code that compiled under implicit settings will fail under the new defaults.
Can I upgrade incrementally from TypeScript 5.9 to 6.0?
Yes, by running tsc --ts6-migration first to identify breaks, then enabling strict mode gradually file by file. The migration flag does not require upgrading the compiler version.
What is the alternative to ES5 compilation?
Compile TypeScript to ES2015, then transpile to ES5 using Babel or SWC. This adds a second build step but preserves legacy browser support.
Does TypeScript 6.0 require Node.js 20+?
No, TypeScript 6.0 runs on Node.js 18+, but the minimum compilation target is ES2015. You can run the compiler on older Node versions but cannot target ES5 output.
How long will TypeScript 6.x receive updates?
TypeScript 6.x will receive updates until the next major version ships, expected in 2027. The team committed to maintaining 6.x as a stable JavaScript-based release during the transition to the new runtime.
Migration Strategy: Step-by-Step Upgrade Path
The safest upgrade path: run tsc --ts6-migration on your current codebase before touching the TypeScript version. Fix every reported issue. Then create a branch and upgrade the TypeScript dependency. Run the build and address strict mode errors file by file. Test the output in staging before deploying.
For teams with large codebases, the incremental approach works: enable strict mode in tsconfig.json, add skipLibCheck: true to suppress dependency errors, and fix your own code first. Once your code passes strict checks, remove skipLibCheck and address dependency type errors through type patches or dependency upgrades.
The migration flag and incremental strict mode enable a phased upgrade across weeks instead of forcing a single high-risk deployment. The compiler's improved performance means the migration itself will run faster, even as it enforces stricter rules.
That covers the essential breaking changes in TypeScript 6.0. Run the migration flag, lock in your tsconfig defaults, and address strict mode errors incrementally. The difference in type safety and build performance will be immediate. For a complete migration walkthrough on a real 200k-line codebase, see TypeScript 5 to 6 Migration: 200k Lines. For detailed configuration strategies, check TypeScript 6 Migration Guide. For context on why this is the final JavaScript-based release, read TypeScript 6: Final JavaScript Release.