TypeScript 7.0: What’s New and What Breaks
TypeScript just went through its biggest architectural shift since the project began. Back in August, I wrote about TypeScript 5.9 and its leaner configs and deferred imports. Since then, the team also shipped TypeScript 6.0 - a release I didn't get around to covering here, but one that turns out to matter a lot in retrospect - and then TypeScript 7.0, a complete native port of the compiler written in Go. If you've been sitting on 5.9, this is not a routine minor-version bump you can skim past. Here's what actually changed, what's safe to ignore, and what will break your build.
TL;DR
TypeScript 5.9 (Aug 2025) is the last "classic" TypeScript most people know well. TypeScript 6.0 (Mar 2026) was the final release built on the original JavaScript codebase - a deliberate transition and cleanup version. TypeScript 7.0 (Jul 2026) is a full rewrite of the compiler in Go, with the same behavior but a radically faster runtime.
The team's own framing is useful here: 6.0 exists specifically to absorb the breaking changes before the engine swap, so that 7.0 itself is "just" a performance release on top of already-adjusted code. If you're upgrading straight from 5.9 to 7.0, you're getting both sets of changes at once.
The Headline Feature: A Native Compiler
TypeScript 7.0 is not incrementally faster - it's a different implementation entirely. The compiler and language service were rewritten in Go, trading the old single-threaded JavaScript engine for native code with real multithreading. In the team's own benchmarks on large open-source codebases, build times on vscode dropped from 125.7s to 10.6s (about 12x faster), sentry went from 139.8s to 15.7s (roughly 9x), and both bluesky and playwright saw builds run about 8.7x faster.
Memory usage dropped too (roughly 6–26% depending on the project), and editor responsiveness improved even more dramatically - opening a file and seeing the first error in the VS Code repo went from ~17.5 seconds to under 1.3 seconds.
Two new flags let you tune this:
--checkers N- number of parallel type-checking workers (default 4). More cores, more speed, more memory.--builders N- number of project references built in parallel under--build, useful for monorepos.--singleThreaded- disables parallelism entirely, handy for debugging or constrained CI environments.
What to watch for: varying --checkers can occasionally surface order-dependent type results in edge cases. If reproducibility across machines matters to your team, pin the value in CI.
--watch mode was also rebuilt from scratch on a Go port of Parcel's file watcher, replacing the old polling-based approach. It should be noticeably lighter on large node_modules trees.
Defaults That Changed (and Will Break Silent Assumptions)
This is the part most people miss. TypeScript 7.0 doesn't just adopt 6.0's new defaults - it hard-enforces them with no escape hatch:
strictnow defaults totrueinstead offalse.modulenow defaults toesnextregardless of target, instead of varying by target.targetnow defaults to the latest stable ECMAScript version beforeesnext, instead of an older fixed version.typesnow defaults to an empty list - ambient@types/*packages are no longer auto-included and must be listed explicitly.rootDirnow defaults to./and must be set explicitly iftsconfig.jsonisn't sitting right next to your source folder - it used to be inferred.noUncheckedSideEffectImportsnow defaults totrue.stableTypeOrderingis now always on and can't be turned off.
The types and rootDir changes are the ones that quietly break the most projects. If your tsconfig.json sits at the repo root but your source lives in src/, you now need:
{
"compilerOptions": {
+ "rootDir": "./src"
},
"include": ["./src"]
}
And if you were relying on ambient @types packages being picked up automatically:
{
"compilerOptions": {
+ "types": ["node", "jest"]
}
}
Options That Are Just Gone
These aren't deprecated with a warning anymore - in 7.0 they're hard errors:
target: es5anddownlevelIterationmoduleResolution: node/node10/classic=> usenodenextorbundlermodule: amd,umd,systemjs,none=> useesnextorpreservebaseUrl=> rewritepathsrelative to the project root insteadesModuleInterop: falseandalwaysStrict: falseare no longer settable- The
modulekeyword can't be used wherenamespaceis expected assertson imports is gone in favor of thewithkeyword (aligning with the import attributes proposal)
If you're currently on 5.9, running the upgrade to 6.0 first with "ignoreDeprecations": "6.0" set will surface all of these as warnings before they become hard failures in 7.0 - genuinely worth doing rather than jumping straight to 7.0 cold.
Smaller Language and Type-System Changes
Not everything is about the compiler internals. A few changes affect how you write types day to day:
- Template literal types now respect Unicode code points. Previously, inferring over a string containing an emoji split it into UTF-16 surrogate halves. In 7.0,
HeadTail<"😀abc">infers["😀", "abc"]instead of splitting the emoji in two. This is a breaking change if you built string-length utilities that depended on the old UTF-16 behavior. RegExp.escape, new Temporal API types, andes2025as a validtarget/libvalue all landed in 6.0.#/-prefixed subpath imports are now recognized.- The
domlib now bundlesdom.iterableanddom.asynciterablerather than requiring them separately. - Method-syntax functions that don't reference
thisnow participate in inference slightly earlier, which can (rarely) change inferred types in generic-heavy code.
JavaScript/JSDoc Support Got Stricter
If you type-check plain .js files with JSDoc, this is the section to read carefully. TypeScript 7.0 reworked JS analysis to align more closely with how .ts files are checked, dropping several Closure-flavored conveniences:
- Values can't stand in for types - use
typeof someValueinstead. @enumis no longer special-cased.- A bare
?is no longer valid as a type; useany. @classno longer makes a function a constructor - use an actualclass.- Postfix
!isn't supported in JSDoc types. - Closure-style function signatures like
function(string): voidmust become(s: string) => void.
What's Not Ready Yet
Worth knowing before you flip the switch project-wide: TypeScript 7.0 ships without a public compiler API. Tools that embed the TypeScript compiler programmatically - typescript-eslint, bundler plugins, and language tooling for Vue, Svelte, Astro, and Angular - can't run on 7.0 yet. The team publishes a compatibility package, @typescript/typescript6, with a tsc6 binary so you can alias your way to running both side by side:
{
"devDependencies": {
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2"
}
}
A new API is expected in 7.1. Until then, projects using framework tooling that embeds TypeScript should keep the editor on 6.0 while using 7.0's tsc for fast CLI type-checking.
Should You Actually Upgrade to 7.0?
There's no universal "yes, do it now" here - it depends on your situation.
It's worth moving to 7.0 if slow builds are a real pain point for your team, whether in CI or local development - an 8–12x speedup is noticeable on any mid-to-large project. It also makes sense if you don't have a hard dependency on tools that hook into the compiler's programmatic API, and if you're willing to spend real time on the migration itself - this isn't a one-click update, since things like rootDir, types, and moduleResolution genuinely break.
On the other hand, it's reasonable to wait if your project relies on Vue, Svelte, Astro, or Angular - their language tooling can't run on TS 7.0 yet, since there's no public compiler API. You'd end up keeping the editor on 6.0 and using 7.0 only for CLI type-checking, which adds setup complexity for little day-to-day benefit. The same goes if you lean heavily on typescript-eslint or other tools that embed the compiler directly - they're waiting on the same API, expected in 7.1. It's also fine to hold off if your project is small enough that build times were never an issue, since the speed gains simply won't be felt in daily work, or if you don't have the bandwidth right now to work through the breaking changes - especially if you're still on 5.9, where jumping straight to 7.0 means absorbing both the 6.0 and 7.0 changes at once.
If you do decide to upgrade, don't jump straight to 7.0. Update to 6.0 first with "ignoreDeprecations": "6.0" set, work through the warnings it surfaces, and only then move to 7.0 - that way the breaking changes land in two manageable batches instead of one big one.
If build speed isn't currently causing you pain, delaying the upgrade costs you nothing - the surrounding ecosystem (types, tooling, framework support) is still visibly catching up to 7.x.
Migration Checklist
- Upgrade to 6.0 first, even briefly, and turn on
"ignoreDeprecations": "6.0"to see every warning without breaking the build immediately. - Fix
rootDirandtypesintsconfig.json- these are the two most common silent breaks. - Search for
moduleResolution: node,classic,baseUrl, andtarget: es5in your configs. - If you rely on tools with deep compiler integration (ESLint, Vue/Svelte/Astro tooling), plan to stay on
@typescript/typescript6for those specific tools. - Re-run your test suite with
strict: true- this alone can surface a meaningful number of new errors in older codebases. - Once on 7.0, experiment with
--checkersand--buildersfor your CI machine's core count before assuming the defaults are optimal.
Further Reading
Conclusion
TypeScript 6.0 and 7.0 aren't feature releases in the usual sense - they're a coordinated migration off a decade-old codebase onto a faster foundation, with 6.0 doing the cleanup and 7.0 delivering the payoff. The type system itself hasn't fundamentally changed; what changed is stricter defaults, a handful of removed legacy options, and a compiler that's an order of magnitude faster. If your project already compiles cleanly on 6.0 with no ignoreDeprecations flag set, moving to 7.0 should be close to a no-op - just faster.