TypeScript 7 Migration in Next.js: What Breaks and How to Fix It
Upgrading Next.js to TypeScript 7? Fix the baseUrl and types errors, keep ESLint working, and make sure next build really uses the new compiler.
CarnielOn this page22 sections
TypeScript 7 is the compiler rebuilt in Go, and the speed is real. The TypeScript team reports full builds running 8 to 12 times faster on large open source projects. Type checking the VS Code codebase dropped from 125.7 seconds to 10.6 seconds (TypeScript 7.0 announcement).
Next.js 16.3 can use it for next build, and the official instructions fit on one line: install typescript@^7. On a real Next.js app, that line is where the trouble starts. An older tsconfig.json stops parsing, test files start failing the production build, and ESLint crashes. The standard fix for ESLint then sends next build back to TypeScript 6 without telling you.
This guide covers the upgrade in four steps, with the exact error for each problem and the fix. Every error message below comes from a Next.js 16.3.8 test app running TypeScript 7.0.2.
I upgraded ALIEAZ, a lipstick e-commerce store I built on my own with Next.js 16, Prisma, Prismic, Stripe and Auth.js. Prisma’s generated client is huge, and every schema change meant waiting for the type check before I could trust a build. On a solo project, that wait is all yours. Nobody else is pushing while you sit there.
Key takeaways
TypeScript 7 typically builds 8 to 12 times faster, but it ships without a programmatic API until 7.1, so typescript-eslint still needs TypeScript 6.
baseUrlis now a hard error, andtypesdefaults to an empty list, so test globals likedescribestop resolving.
next buildtype checks with whatever packagetypescriptresolves to. With the recommended npm aliases, that is TypeScript 6, so runtsc --noEmityourself to get the speedup.In CI, run
next typegenbeforetsc --noEmit, becausenext-env.d.tsshould no longer be committed.
What TypeScript 7 changes for a Next.js app
Three changes matter when you upgrade a Next.js project.
It is much faster. Besides the full build numbers above, TypeScript 7 usually uses less memory, and the team says Slack cut CI type checking from about 7.5 minutes to 1.25 minutes. Editor start-up gets the same treatment: opening a file with an error in the VS Code repo went from about 17.5 seconds to under 1.3 seconds.
It is strict about old config. TypeScript 7 adopts the new defaults from TypeScript 6.0, and every flag 6.0 deprecated is now a hard error. Code that compiles cleanly on 6.0 without ignoreDeprecations should compile the same way on 7.0.
It has no API yet. TypeScript 7.0 ships the tsc command but not the JavaScript compiler API that tools import. The team expects a new, different API in 7.1. Until then, anything that calls require("typescript") needs TypeScript 6.
Next.js 16.3 works around that last point. By default, next build now runs your project's tsc command instead of loading the API (Next.js TypeScript docs). Two side effects follow. Errors print as raw tsc output, without the Next.js code frames you are used to. And the check covers every file your tsconfig.json includes, test files too.
If you haven't upgraded Next.js yet, my guide to what's new in Next.js 16.3 covers the rest of the release.
Before you start
Treat this like a move: check what you own before you pack. Make sure you have:
Next.js 16.3 or later. Older versions load the compiler API and can't use TypeScript 7 for
next build.TypeScript 6.0 first, if you're on 5.x. The TypeScript team recommends this step, because 6.0 warns about everything 7.0 rejects.
A list of tools that import TypeScript. In most Next.js apps that means typescript-eslint, which
eslint-config-nextpulls in. Also look for ts-jest, ts-morph and ts-node.A baseline time. Run
time npx tsc --noEmitnow, so you can compare later.
ALIEAZ has roughly 120 to 200 TypeScript files plus the Prisma client. On a project that size, expect npx tsc --noEmit on TypeScript 6 to take around 8 to 15 seconds on an M1 Pro, and the type check inside next build to add roughly 15 to 30 seconds to each CI run on GitHub Actions.
Step 1: Choose how to install TypeScript 7
You have two layouts, and the choice decides which compiler each tool gets.
Option A: TypeScript 7 alone
npm install -D typescript@^7This is what the Next.js docs show, and next build picks it up with no config. The problem is ESLint. typescript-eslint 8.71.1, the latest release, still requires TypeScript below 6.1. npm installs anyway and only warns about the peer range, then the first lint run fails:
typescript-eslint does not support TS 7.0.
Please see https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/#running-side-by-side-with-typescript-6.0 to run typescript-eslint using the TS 6 API.Option A only works if nothing in your project imports the TypeScript API. Support in typescript-eslint is being tracked for TypeScript 7.1 (typescript-eslint issue #10940).
Option B: TypeScript 6 and 7 side by side
The TypeScript team's answer is a compatibility package, @typescript/typescript6, installed under the name typescript with an npm alias. TypeScript 7 goes in under a second name:
{
"devDependencies": {
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2"
}
}Now npx tsc runs TypeScript 7, npx tsc6 runs TypeScript 6, and anything that imports typescript gets the 6.0 API. ESLint works again.
The catch: next build now uses TypeScript 6
Here is the part most upgrade guides miss. Next.js finds its type checker by resolving typescript/package.json and running that package's tsc binary, falling back to a numbered one like tsc6. With the aliases, typescript is the TypeScript 6 package, so next build type checks with TypeScript 6.
I confirmed this in the Next.js 16.3.8 source and in the test app. A type that only TypeScript 7 accepts passed npx tsc and failed next build. Nothing in the build output says which version ran. To check your own setup:
node -p "require('typescript/package.json').version"So with Option B, your production build gets no faster. The speedup comes from running tsc yourself, which Step 3 sets up.
Step 2: Fix your tsconfig.json
Run npx tsc --noEmit and work through the errors in order. Config errors stop the check before any code is read, so they come first.
baseUrl is gone
Many Next.js projects created before 2024 still have "baseUrl": ".". TypeScript 7 refuses it:
error TS5102: Option 'baseUrl' has been removed. Please remove it from your configuration.
Use '"paths": {"*": ["./*"]}' instead.Delete the line. If your paths entries don't start with ./, you get a second error once baseUrl is gone:
error TS5090: Non-relative paths are not allowed. Did you forget a leading './'?Add the ./, so "@/*": ["src/*"] becomes "@/*": ["./src/*"]. Paths now resolve from the folder that holds tsconfig.json. If your imports relied on baseUrl alone, like import Button from "components/Button", add the "*": ["./*"] mapping from the error message.
types defaults to an empty list
TypeScript used to load every package in node_modules/@types automatically. Now it loads none unless you list them. In a Next.js app, process.env kept working in my test, because next-env.d.ts pulls in the Next.js types. Test files did not:
src/lib/env.test.ts(2,1): error TS2593: Cannot find name 'describe'. Do you need to install type definitions for a test runner?Because next build now checks test files, this error fails your production build too. List the globals you use:
{
"compilerOptions": {
"types": ["node", "jest"]
}
}For Vitest with globals turned on, use "vitest/globals" instead of "jest".
Other options that are now errors
Current create-next-app configs already avoid these, but older projects may still have them: target: "es5", downlevelIteration, moduleResolution: "node" (use "bundler"), and esModuleInterop: false. The announcement lists every removed option.
Clear the incremental cache after editing
Next.js turns on "incremental": true, which writes a tsconfig.tsbuildinfo file. In my test, TypeScript 7.0.2 kept reporting the old describe errors after I added types, until I deleted that file. TypeScript 6.0.3 picked up the same change straight away. If an error survives a config fix, delete the cache and run again:
rm -f tsconfig.tsbuildinfo && npx tsc --noEmitStep 3: Type check with TypeScript 7 in CI
Add a script that runs TypeScript 7 directly:
{
"scripts": {
"typecheck": "next typegen && tsc --noEmit"
}
}The next typegen part matters. The Next.js docs now say to keep next-env.d.ts out of Git, so a clean CI checkout doesn't have it. Without that file, tsc can't see the Next.js types or your generated route types. next typegen writes them without running a build.
Then order your pipeline so the fast checks run first:
With Option B, next build still runs its own TypeScript 6 check after this. You can skip that second pass with typescript.ignoreBuildErrors: true in next.config.ts, but only if the typecheck step always runs before every build, including on your hosting platform. If you deploy straight from Git without a CI gate, leave the build check on. A slow check beats shipping a type error.
One more setting for CI. TypeScript 7 type checks with 4 workers by default, set by the new --checkers flag. Small CI runners may do better with --checkers 2. The team notes that changing the count can, in rare cases, change results, so use the same number everywhere.
Step 4: Measure the difference
Compare both compilers on the same code, with the incremental cache turned off so neither gets a head start:
time npx tsc6 --noEmit --incremental false
time npx tsc --noEmit --incremental falseFor a project this size, expect TypeScript 6 to take around 8 to 15 seconds and TypeScript 7 around 1.5 to 3 seconds, roughly 4 to 6 times faster. That’s well short of the 10x benchmarks, because those come from codebases where a check takes minutes. The bigger change shows up in the editor: after running prisma generate, the red squiggles on product and order types update almost instantly instead of lagging behind.
Small apps won't see the 10x figures. Those come from codebases like VS Code and Sentry, where a check takes minutes. On a mid-sized Next.js app the absolute saving is smaller, but you feel it most in the editor, where every red squiggle comes from the same compiler.
Troubleshooting
Errors no longer show Next.js code frames
This is expected. The CLI checker prints tsc output as is (useTypeScriptCli docs). File paths and line numbers are still there.
The Next.js editor plugin stopped warning me
The "next" entry in your tsconfig.json plugins is a language service plugin. The TypeScript team recommends TypeScript 7 in the editor only where such plugins aren't needed. If you rely on those warnings, run "Disable TypeScript 7 Language Server" in VS Code and keep TypeScript 7 for the command line.
Projects with MDX pages
Type checking inside MDX depends on tools that embed TypeScript, and the team says these need TypeScript 6 for now. Your .ts and .tsx files can still use TypeScript 7 at the command line.
FAQ
Should I wait for TypeScript 7.1?
Wait if your project depends on tools that need the compiler API and you don't want two TypeScript versions installed. Otherwise, upgrade now. The config fixes in Step 2 are valid on TypeScript 6 as well, so you lose nothing by making them today.
Does TypeScript 7 make next dev faster?
Not directly. Next.js compiles TypeScript with SWC, which removes types without checking them, so next dev never ran tsc. You get the speedup in next build, in CI, and in your editor.
Can I roll back?
Yes. Reinstall typescript@^6 and remove the aliases. Removing baseUrl and listing types are TypeScript 6 defaults too, so your fixed config keeps working.
Conclusion
The TypeScript 7 upgrade is mostly config cleanup that TypeScript 6 already asked for. The trap is the ESLint workaround: it fixes linting and quietly hands next build back to TypeScript 6. Check which version your build uses, run tsc yourself in CI, and you get the speed where it counts.
Try it on a branch this week, starting with npx tsc --noEmit on TypeScript 7. If you're also caching data in your app, my guide to use cache in Next.js 16 is a good next read.