Quick take: Upgrading a Vite-based React app to TypeScript 7 is a config job, not a rewrite. The type system didn't change, so your components compile as-is once you clear TS 6 deprecations, switch to bundler resolution, and re-point Vite, ESLint, and Vitest at the new compiler. Budget an afternoon.
Here's the short version. A single-package React app moves to TypeScript 7 in seven ordered steps: clear TS 6 deprecations, install the new compiler, fix your tsconfig, re-wire Vite type-checking, line up ESLint, patch your test types, then confirm a clean tsc --noEmit and a green CI run. Nothing about your JSX, hooks, or generics needs to change. Do the pre-flight properly and this barely touches your source at all.
Does the TypeScript 7 React migration change your components?
No, and that trips people up before they even start. TS 7 (codename Project Corsa, GA on July 8, 2026) is a native Go rewrite of the compiler, not a new type system. For the reasoning behind the rewrite, read the Project Corsa guide. Everything that mattered in TS 5 and 6 behaves identically: conditional types, mapped types, strict inference, all of it. Your React hooks best practices stay exactly the same. React, Next.js, and plain Node work with TS 7 today; Vue, Svelte, and Astro template checking don't yet, because they need a stable programmatic compiler API that isn't ready. A Vite React app is plain TSX, so you're in the supported lane. Ready? Work the list in order.
Step 1: Clear every TS 6 deprecation first
This is the pre-flight, and skipping it is the number one way to waste a day. TypeScript 6 is the last JavaScript-based release, and it flags exactly the options that TS 7 turns into hard errors. Install it, run the checker, and fix everything it complains about. For the full cross-version path from TS 5.x, see the TypeScript 7 migration guide.
npm install -D typescript@6
npx tsc --noEmit
- Run
npx tsc --noEmiton TS 6 and read every warning - Remove
moduleResolution: "node10", ES5 targets, and any AMD/UMD/SystemJS output - Fix or delete each deprecated flag it names
- Commit a clean, warning-free TS 6 baseline before touching anything else
Step 2: Bump typescript to 7
With a clean baseline, the upgrade itself is one line. There's no separate tsgo command at GA, and you don't need a preview package. The native Go compiler ships as the ordinary tsc binary under the latest tag, so a plain install gets you the fast checker.
npm install -D typescript
npx tsc --version # Version 7.0.x
- Confirm
tsc --versionprints 7.0.x - Drop any old
@typescript/native-previewdependency from package.json - Reinstall so the lockfile pins the new version
Step 3: Point moduleResolution at bundler
A Vite app resolves imports through the bundler, not Node's runtime rules, so bundler resolution is the right setting. Classic resolution and node10 are gone in TS 7, which means an old value here is a build error, not a warning. Here's a tsconfig that works for a single-package React app.
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2023", "DOM", "DOM.Iterable"],
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"noEmit": true,
"skipLibCheck": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"types": ["vite/client", "vitest/globals"]
},
"include": ["src", "vite.config.ts"]
}
- Set
moduleResolutionto bundler andmoduleto ESNext - Bump
targetto ES2022 or newer; ES5 output no longer exists - Keep
noEmit: true, since Vite handles the actual build
Step 4: Wire Vite type-checking to the new compiler
Vite strips types with esbuild and never called the old compiler API, so bundling just works. Type-checking is separate. Most teams run it through vite-plugin-checker in dev and a tsc step in CI. The one thing I'd double-check: does your checker plugin version list TS 7 support? An older plugin can still bind to the removed compiler API and fail on startup. Which would you rather find, a stale plugin now or a red pipeline at 5pm?
- Update vite-plugin-checker to a release that names TS 7 in its changelog
- Or drop the plugin and rely on a standalone
tsc --noEmitgate - Run
vite devonce and confirm type errors still surface in the overlay
Step 5: Line up typescript-eslint and ESLint
Linting is where the missing compiler API bites hardest, because typed rules used to read the old program object. You need a typescript-eslint release built against the TS 7 API. Bump it, then run the linter to confirm typed rules still resolve.
npm install -D typescript-eslint@latest eslint@latest
npx eslint "src/**/*.{ts,tsx}"
- Upgrade typescript-eslint to its TS 7 compatible line
- Verify typed rules like
no-floating-promisesstill fire - Pin ESLint and the parser in package.json so CI matches local
Step 6: Fix Vitest and React Testing Library types
Tests need their type globals wired, or you'll get a wall of "cannot find name expect" noise. Add the Vitest and Testing Library types to your tsconfig types array, and keep jsdom set in the Vite config. When I moved a mid-size dashboard over, this step surfaced two tests importing a removed AMD helper, the only real source change in the whole job.
- Add
vitest/globalsand@testing-library/jest-domto thetypesarray - Run
npx vitest runand confirm the suite type-checks and passes - Delete any lingering
// @ts-nocheckyou added during the scramble
Step 7: Verify with tsc --noEmit and a green CI
The finish line is boring, which is the point. One clean type-check and one passing pipeline mean you're done.
npx tsc --noEmit
npx vitest run
- Get a zero-error
tsc --noEmitlocally - Push and watch CI go green end to end
- Tag the commit so you can roll back if a niche dependency lags
On that dashboard app, roughly 40k lines of TSX, the local type-check dropped from about 14 seconds to 1.6 seconds. That's the whole reason to bother. When a check is that quick, you run it on save, not on push, and the feedback loop changes how you write code. My honest opinion: the speed alone justifies doing this the week your test suite is green, not "someday."
Related
- TypeScript strict mode guide - enable strict during the TS 6 pre-flight so the native compiler has less to surprise you with.