TypeScript 7 is 8-12x faster, which makes the upgrade tempting to do on a Friday afternoon. Don't. The speed is real, but 7.0 is the release where the team cashed in every deprecation they've been sitting on and shipped without a programmatic API. Whether you can move depends less on your code than on your toolchain.
Here's the honest checklist, in the order the breakage actually hits you.
1. Options that are now hard errors
TypeScript 6 made these warnings. TypeScript 7 makes them errors, so tsc refuses to start
rather than silently doing something else. Removed outright:
| Removed | What to do instead |
|---|---|
target: es5 | Target a modern runtime; downlevel in your bundler if you truly must |
downlevelIteration | Gone with ES5 |
moduleResolution: node / node10 | nodenext (Node) or bundler (Vite, webpack, Next) |
module: amd / umd / systemjs / none | esnext |
baseUrl | paths, resolved relative to the project root |
esModuleInterop: false, allowSyntheticDefaultImports: false | Cannot be disabled; delete them |
If you're on a modern setup, most of this is a no-op. If you're carrying a tsconfig.json
that has been copy-pasted since 2019, this is where your afternoon goes.
2. Defaults that changed under you
More dangerous than the removals, because these don't error, they just change what your build means.
-
strict: trueis the default. If you were implicitly relying onstrictbeing off, you now have every errorstrictcatches, all at once. Set"strict": falseexplicitly if you're not ready — but note you're now opting out, in writing, which is the point. -
module: esnextis the default. -
noUncheckedSideEffectImports: true— a bareimport "./thing"that resolves to nothing is now an error. This catches real bugs and a few false ones (side-effect imports of CSS or assets need the right ambient declarations). -
stableTypeOrdering: true, and it cannot be disabled. The checker is parallel now, so deterministic type ordering has to be enforced rather than assumed. -
rootDirnow defaults to./. If yourtsconfig.jsonlives above your sources, your output layout just changed. Say what you mean:{ "compilerOptions": { "rootDir": "./src" } } -
typesdefaults to[]instead of auto-discovering everything innode_modules/@types. This is a genuinely good change (auto-discovery was a common source of "why isdescribea global in my production build") and a genuinely annoying one, because you must now list what you use:{ "compilerOptions": { "types": ["node", "vitest/globals"] } }Missing globals after upgrading —
process,describe,expect— is almost always this.
3. Checked JavaScript got stricter
If you run checkJs over a JS codebase with JSDoc types, several patterns are gone: values
can no longer stand in for types (use typeof x), @enum is no longer recognized (use
@typedef), the postfix ! non-null operator is out, and Closure-style function syntax
isn't supported. Small surface, but if you're a big JSDoc shop it's the whole migration.
4. The one that actually decides your timeline: no API
TypeScript 7.0 ships with no programmatic API. Anything that imports typescript and
walks the AST or asks the checker questions does not work on 7 yet. That includes:
- typescript-eslint (so: most people's lint setup)
- Vue, Svelte, Astro, MDX — anything that embeds or templates TypeScript
- Angular's template type-checking
- ts-morph, most codemods, most custom transformers
The supported path is to run both compilers side by side: TypeScript 7 for the fast CLI
builds, TypeScript 6 via @typescript/typescript6 (an npm alias) for the tools that still
need the API. A real API is expected in 7.1.
So the practical question is not "does my code compile under 7" but "which of my tools reach into the compiler". Most teams will find the answer is at least one.
What this means for a site like this one
This site is Next.js App Router plus MDX (that's how these threads are written). MDX needs
the TypeScript API to type-check inside .mdx, so per the release notes, MDX projects stay
on TypeScript 6 for now. The realistic setup is split:
- CLI type-check and CI: TypeScript 7.
npm run typecheckis the single slowest thing in our pipeline, and it's the thing every push waits on. - Editor and lint: TypeScript 6 until 7.1 lands the API, because typescript-eslint and the MDX toolchain need it.
That's not a clean win, and it's worth being clear-eyed about it rather than performing an upgrade for the changelog entry. A codebase this size type-checks in a couple of seconds either way. The 8-12x is transformative for a 130-second build and a rounding error for a 2-second one, so we'll take the CI half now and move the editor when the API is real.
A migration order that works
- Upgrade to the latest TypeScript 6 first, and fix every deprecation warning. This is the actual work, and you can do it incrementally while your tooling still functions.
- Modernize
tsconfig.json:moduleResolutiontobundlerornodenext, dropbaseUrl, dropesModuleInterop: false, makerootDirandtypesexplicit. - Turn
stricton, or explicitly turn it off, so nothing changes silently under you. - Inventory what touches the compiler API: lint, test transforms, codemods, framework plugins. That list is your gate.
- Run TypeScript 7 for CLI builds and CI, keep TypeScript 6 wherever the API is required.
- Revisit when 7.1 ships an API and the ecosystem catches up.
Steps 1-3 are worth doing even if you never adopt 7. That's usually the sign of a well-designed breaking release: the migration path improves your codebase whether or not you arrive at the destination.
