Why Your TypeScript 7 Upgrade Broke ESLint, ts-jest, and ts-morph
TypeScript 7's native compiler breaks typescript-eslint, ts-jest, and ts-morph. Here's exactly why, and the side-by-side setup that fixes it.
On this page
You installed TypeScript 7, ran your build, and something broke. Maybe ESLint crashed with a cryptic TypeError: Cannot read properties of undefined (reading 'Cjs'). Maybe ts-jest stopped transforming your test files. Maybe your CI pipeline just went red for no reason you can point to.
You're not doing anything wrong. TypeScript 7 shipped tsgo, a genuine Go port of the type-checker, not a rewrite from scratch. But the tools that plug into TypeScript don't talk to the type-checker directly, they talk to a programmatic API. That API isn't stable yet. It lands in 7.1. Until then, a chunk of the ecosystem throws errors the moment you point typescript at the new version.
Here's what's actually happening, which tools are affected, and the fix that gets you the faster type-checking without breaking everything else.
The 10-Second Version
That's the pattern. The rest of this post covers why it works and how to wire it up, tool by tool.
Why This Is Happening
TypeScript's team calls this Project Corsa. The pitch: rewrite the compiler in Go, keep identical type-checking behavior, get roughly 10x faster builds by using real OS threads instead of Node's single-threaded event loop. It shipped as a release candidate on June 18, 2026, with general availability targeted about a month out. We covered the rewrite itself in TypeScript 7 (Project Corsa): What Next.js Devs Need to Know, which explains what changed under the hood and why Microsoft picked Go. This post assumes you already know that part and covers a different problem: what happens when your existing toolchain points at the new compiler.
The detail that gets lost in the "10x faster" headline: this is a port, not a reimplementation with a new API surface. The team moved the existing structure file by file from the old JavaScript codebase (they call it Strada) into Go (Corsa). That preserved identical type-checking semantics, which is genuinely impressive engineering. What it didn't preserve is the programmatic API surface that tools like typescript-eslint depend on to walk your AST and pull type information out of the compiler. That stable API is scheduled for 7.1, not 7.0.
So when you run npm install typescript@7, you get a fast compiler binary. You do not get a drop-in replacement for every place your old TypeScript 6 install was quietly doing double duty as both a CLI tool and a library other tools import at the code level.
What's Actually Broken Right Now
This is based on live GitHub issues filed in the weeks around the release candidate, not speculation. If you upgraded and hit an error, it's almost certainly one of these four.
typescript-eslint
This is the big one. If you have typescript-eslint in your devDependencies with the current published peer range, npm refuses to install alongside typescript@7 at all, because the peer range only allows versions below 6.1.0. That refusal shows up as an ERESOLVE error before you ever run a lint.
Force the install anyway with --force or --legacy-peer-deps and ESLint crashes with TypeError: Cannot read properties of undefined (reading 'Cjs') deep inside typescript-estree. This is a real, reproducible crash tracked as typescript-eslint issue 12518, filed July 8, 2026 and closed as not planned, since the fix is genuinely on the TypeScript 7.1 side, not typescript-eslint's.
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: your-app@1.0.0
npm error Found: typescript@7.0.0-rc
npm error node_modules/typescript
npm error typescript@"^7.0.0-rc" from the root project
npm error
npm error Could not resolve dependency:
npm error peer typescript@"<6.1.0" from typescript-eslint@8.x
npm error node_modules/typescript-eslint
npm error typescript-eslint@"^8.0.0" from the root projectIf you've never had to untangle an ERESOLVE error by hand, our ERESOLVE Explainer tool parses the exact output above (or your own) and generates the overrides block you need, faster than tracing the dependency tree line by line yourself.
ts-jest
ts-jest mostly survives if you leave typescript pointed at 6.x in node_modules and only use tsgo separately for type-checking. If you try to make ts-jest itself resolve to @typescript/native-preview, it breaks, because ts-jest calls internal Strada APIs that Corsa doesn't expose yet. The error surfaces as a transform failure, not an install failure, which makes it more confusing to diagnose: your tests just start failing with unhelpful stack traces pointing into ts-jest's internals rather than your own code.
ts-morph and Custom AST Transformers
ts-morph and any custom AST transformer are in the same boat as typescript-eslint: anything doing deep programmatic type introspection needs the 7.1 API and isn't safe to point at the native preview yet. If your build pipeline includes a custom transformer (code generation, decorator metadata, schema extraction from types), audit it before upgrading, since these tools tend to fail silently or produce subtly wrong output rather than crashing outright.
Monorepos with Project References
Monorepos hit their own category of pain. The WordPress Gutenberg team, migrating an 84-package monorepo, logged a real issue in March 2026: tsgo drops generic type parameters from JSDoc @typedef declarations that use @template, which matters if you're a JS-plus-JSDoc codebase rather than pure .ts. They also found that skipLibCheck: true doesn't suppress certain parse-level errors from third-party .d.ts files, so some previously-silent type-check noise becomes build-breaking noise. tldraw opened a similar tracking issue for their own 44-tsconfig monorepo.
A separate compatibility survey published in April 2026 tested 15 popular pipeline tools against the native preview and found 9 of them call Strada API functions that no longer exist. That's the concrete version of the abstract problem above: most teams need a side-by-side setup rather than a straight swap, and that ratio (9 out of 15) is a useful gut check for how far the ecosystem still has to go before 7.1 closes the gap.
Tool Compatibility Matrix
| Tool | Status with typescript@7 | What to do |
|---|---|---|
| tsc (CLI, emit + type-check) | Compatible | Works as-is, no change needed |
| tsgo (native preview binary) | Compatible | Use for fast --noEmit type-checking only |
| typescript-eslint | Broken | Keep typescript pinned to 6.x, don't touch parser config |
| ts-jest | Needs side-by-side | Keep typescript at 6.x in node_modules for tests |
| ts-morph | Needs side-by-side | Wait for the 7.1 programmatic API |
| Custom AST transformers | Needs side-by-side | Audit against the 7.1 API before upgrading |
| VS Code (tsserver) | Compatible | Use the TypeScript Native Preview extension separately |
The Side-by-Side Fix
Here's the setup that gets you fast type-checking without breaking your existing tools. It takes about five minutes to wire up.
- 1
Keep typescript pinned to 6.x for your tools
Don't touch your existing
typescriptdevDependency. Leave it on the 6.x line so typescript-eslint, ts-jest, and ts-morph keep resolving against an API surface they actually understand.bashnpm install -D typescript@^6.9 - 2
Install the native preview alongside it
Add
@typescript/native-previewas a second, separate devDependency. This istsgo, used only for checking, never for anything your linter or test runner touches.bashnpm install -D @typescript/native-preview - 3
Add a separate typecheck script
Keep
tscdoing what it already does (emit, or type-check via your existing build script). Add a new script that runstsgopurely for fast type-checking.json โ package.json{ "scripts": { "typecheck:fast": "tsgo --noEmit", "build": "tsc" } } - 4
Run the fast check as an early, cheap CI step
In CI, run
typecheck:fastearly so a real type error fails the pipeline fast, before you spend time on the slower full build.yaml โ .github/workflows/ci.yml- name: Fast type check (tsgo) run: npx tsgo --noEmit - name: Build run: npm run buildIf you're setting up GitHub Actions for the first time, our GitHub Actions tutorial covers general workflow setup, triggers, and caching.
- 5
Leave typescript-eslint's config untouched
Don't set typescript-eslint's parser options to point at
@typescript/native-preview. Leave it resolving to your pinned 6.x install and it keeps working exactly like it did before the upgrade.
You get the speed where it actually helps (the fast CI feedback loop) without asking every downstream tool to understand a compiler API that doesn't exist yet.
tsconfig Changes That Bite You Anyway
Even if none of your tools break, TypeScript 7 hard-adopts some strict defaults that catch people who skipped the TypeScript 6 release entirely. These aren't Corsa-specific bugs, they're default changes that happen to surface at the same time as the compiler rewrite.
- `rootDir` now defaults to
./instead of being inferred from your source files. - `types` defaults to an empty array, so ambient type packages you were relying on implicitly stop being picked up.
- `target: "es5"` is removed as an option entirely.
- `moduleResolution: "node"` (the old classic mode) is removed, you need
node16,nodenext, orbundler. - `baseUrl` without `paths` is removed as a standalone option.
Audit your tsconfig before you upgrade even the type-checking-only tsgo binary. If you'd rather start from a config that's already compatible with these defaults, the TSConfigBuilder tool generates one from the ground up, useful for new projects or as a reference when auditing an existing config.
When to Actually Cut Over
Wait for 7.1's stable programmatic API before you drop the side-by-side setup and point everything at typescript@7 directly. If your project genuinely doesn't use typescript-eslint, ts-morph, or custom transformers, and you're just running tsc for type-checking and emit, you can move to 7.0 straight away once it hits general availability. Most real-world codebases aren't that lucky, and the side-by-side setup above costs you nothing while you wait.
For the broader migration picture, including the tsconfig audit steps and CI rollout pattern in more depth, see our full TypeScript 7 Migration Guide.
Frequently Asked Questions
Does running two compilers side by side hurt build speed?
No. tsgo --noEmit as a separate, fast, early CI step is additive, not a replacement. You're not swapping out your existing build, you're adding a faster pre-check in front of it that fails loudly and quickly when there's a real type error.
Is TypeScript 7 stable enough for production right now?
The release candidate is stable enough to benchmark and stage a migration against, per Microsoft's own guidance. Gate your actual cutover on the general availability announcement and a full pass of your own test suite, not just the RC label alone.
What breaks specifically in monorepos with project references?
Expect the most friction here of any project shape. Test tsgo against your full project reference graph before rolling it out team-wide, and check for JSDoc generic parameter issues specifically if you have JS files using @typedef and @template, since those are dropped by the current native preview.
Where do I file a bug if I hit something not covered here?
File against microsoft/typescript-go on GitHub, not the main microsoft/TypeScript repo. Bug reports for the release candidate specifically go to the typescript-go tracker, since that's where the Corsa-side maintainers are watching.
How is this different from your TypeScript 7 migration guide?
Our TypeScript 7 Migration Guide covers language-level breaking changes: removed import assertions, JSDoc @enum removal, and prototype reassignment inference. This post covers a different failure mode entirely: your language-level code is fine, but the tools sitting on top of the compiler (ESLint, Jest, ts-morph) crash or silently misbehave because their programmatic API dependency isn't ready yet. Read the migration guide for tsconfig and language changes, read this one when your toolchain itself is broken.
How do I fix the npm ERESOLVE error when installing typescript-eslint with TypeScript 7?
Don't force the install. Instead, keep typescript on the 6.x line in your dependencies (typescript-eslint's peer range already expects this) and install @typescript/native-preview as a separate package for tsgo. If you already have a tangled lockfile from a previous forced install, paste the exact npm error into the ERESOLVE Explainer to get the two conflicting packages named and a generated overrides block:
{
"overrides": {
"typescript-eslint": {
"typescript": "^6.9.0"
}
}
}Related Articles
TypeScript 7 Migration Guide: tsgo, Breaking Changes, Build Times
Migrate to TypeScript 7 (tsgo): install the beta, fix the 4 breaking changes, update tsconfig, and decide if upgrading now is worth it.
Drizzle ORM Migrations: A Practical drizzle-kit Guide
Learn the full Drizzle ORM migration workflow: push vs migrate, drizzle-kit setup, Turso/libSQL config, team conflicts, and production best practices.