Fix "Parsing error: Cannot find module next/babel"
Resolve ESLint's 'Cannot find module next/babel' error by updating .eslintrc.json and aligning with Next.js 13+ SWC/Babel config. Includes monorepo fixes.
TL;DR#
If you're seeing Parsing error: Cannot find module 'next/babel', the cause is usually ESLint trying to use the deprecated babel-eslint parser or misconfigured parserOptions that point to a non-existent next/babel module — especially in Next.js 13+ projects where SWC is the default compiler. Fix it by updating .eslintrc.json to use eslint-config-next v5+, set parser: '@typescript-eslint/parser' (or omit it), and ensure parserOptions.project points to valid tsconfig.json files.
If that doesn't work, scroll to verify the fix — there are two common variants this guide also covers.
What you'll see#
Parsing error: Cannot find module 'next/babel'
Require stack:
- /Users/mahdi/Projects/my-next-app/node_modules/@typescript-eslint/eslint-plugin/dist/index.js
- /Users/mahdi/Projects/my-next-app/node_modules/eslint/lib/cli-engine/config-array-factory.js
It happens when you open a .ts or .tsx file in VS Code (or run npx eslint .) in a Next.js 13+ project — especially after upgrading from Next.js 12 or initializing a new App Router project. The behavior is the same across macOS, Linux, and Windows, and affects both next dev and next build workflows.
This error does not prevent your app from compiling or running — it only breaks ESLint’s static analysis. Your app may work fine in the browser while your editor shows red squiggles and fails lint checks.
Root cause#
Next.js 13+ switched to SWC as the default compiler and deprecated the next/babel preset. ESLint, however, runs in its own Node.js context and doesn’t inherit Next.js’s runtime module resolution. When you use eslint-config-next v4 or earlier, or manually set parser: 'babel-eslint', ESLint tries to load next/babel as a parser — but that module no longer exists in node_modules/next/dist/build/eslint.
The relevant code path is:
// node_modules/@typescript-eslint/eslint-plugin/dist/index.js
// (simplified for illustration)
const parserPath = require.resolve('next/babel', { paths: [process.cwd()] });
// throws: Cannot find module 'next/babel'
This fails because of how ESLint resolves the parser — not because the preset was deleted. next/babel still ships inside the next package. But Next.js 13+ defaults to the SWC compiler, so a fresh project never installs the Babel toolchain, and any ESLint config that points at next/babel as a parser — for example parser: 'babel-eslint' or parserOptions: { parser: 'next/babel' } — can no longer resolve it.
The deeper issue is that ESLint’s parser resolution is not aware of Next.js’s internal compiler configuration. It only resolves modules from where ESLint runs, and if next isn’t resolvable from there — a monorepo workspace, a missing dependency, or a stale Babel-based config — then require.resolve('next/babel') throws. Meanwhile next dev works because Next.js compiles with SWC internally — ESLint is a separate tool with its own resolution rules.
The fix#
// .eslintrc.json
{
"extends": [
"next/core-web-vitals"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["./tsconfig.json"],
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"@typescript-eslint/no-unused-vars": "error"
}
}
That single change addresses the cause because eslint-config-next v5+ (bundled with next@13+) automatically configures ESLint to use @typescript-eslint/parser and skips the deprecated next/babel path entirely. By explicitly setting parser and parserOptions.project, you ensure ESLint resolves TypeScript files against your actual tsconfig.json, not against a phantom Babel preset.
Step by step#
- Open
.eslintrc.json(or.eslintrc.jsif you use JS config). - Locate any
parser: 'babel-eslint'orparserOptions: { parser: 'next/babel' }entries. - Replace the entire config with the snippet above — ensure
extendsuses"next/core-web-vitals"(not"next"alone). - Save and restart the ESLint server in VS Code (Cmd/Ctrl+Shift+P → “ESLint: Restart ESLint Server”).
If you use a monorepo (e.g., Nx or Turborepo), adjust parserOptions.project to include all relevant tsconfig.json paths — see Special Case: Monorepos below.
Verify the fix#
Run:
npx eslint .
You should see:
All files passed linting.
Found 0 errors.
Instead of:
Parsing error: Cannot find module 'next/babel'
If you’re still seeing the error, two common variants exist:
Variant A — ESLint still references next/babel after config update#
This usually means VS Code’s ESLint extension is caching an old config. Clear it by:
# Kill the ESLint server process
npx eslint --cache --cache-location .eslintcache
# Then restart VS Code or run:
npx eslint --init
Or manually delete .eslintcache and restart VS Code.
Variant B — You’re using next/babel in .babelrc or babel.config.js#
Next.js 13+ does not use .babelrc or babel.config.js by default — it uses next.config.js for compiler settings. If you have a Babel config file, ESLint may still try to load next/babel as a preset. Remove it unless you explicitly need Babel (e.g., for custom plugins). If you must keep it, ensure:
// babel.config.json
{
"presets": [
["next/babel", { "preset-env": { "useBuiltIns": "usage" } }]
]
}
But better yet: delete the file and let Next.js handle Babel/SWC internally.
Why this happens (and how to avoid it next time)#
The root invariant is: ESLint and Next.js have separate module resolution contexts. ESLint runs in Node.js with node_modules resolution, while Next.js uses its own internal bundler that resolves next/babel at runtime — not via standard require(). This mismatch causes ESLint to fail when it tries to load a module that only exists in Next.js’s internal build pipeline.
To prevent regression, adopt these three practices:
-
Pin
eslint-config-nextto v5+ — add topackage.json:json"devDependencies": { "eslint-config-next": "^14.2.0" }Then run
npm installoryarn install. -
Disable
babel-eslintglobally — add to.vscode/settings.json:json{ "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"], "eslint.options": { "extensions": [".js", ".jsx", ".ts", ".tsx"] } } -
Add a CI lint check — in
package.json:json"scripts": { "lint": "next lint" }And in
.github/workflows/ci.yml:yaml- run: npm run lint
I cover this in detail in Deploying Next.js + Supabase to Production, where we enforce linting as part of the CI pipeline to catch these issues before they reach staging.
Special Case: Monorepos (Nx, Turborepo, Lerna)#
In monorepos, ESLint’s parserOptions.project must point to all tsconfig.json files — not just the root one. For example, in an Nx workspace:
// .eslintrc.json
{
"extends": ["next/core-web-vitals"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": [
"apps/*/tsconfig.json",
"libs/*/tsconfig.json"
],
"sourceType": "module"
}
}
If you omit this, ESLint can’t resolve types across workspaces and defaults to next/babel — which doesn’t exist. This is why next lint works in Nx but npx eslint apps/web/src/page.ts fails.
For Turborepo, ensure turbo.json includes ESLint in the pipeline:
{
"pipeline": {
"lint": {
"outputs": ["{workspaceRoot}/.eslintcache"],
"cache": false
}
}
}
And run turbo run lint — not npx eslint directly — to leverage Turborepo’s workspace-aware resolution.
Modern Alternative: Transitioning from Babel to SWC#
Next.js 13+ defaults to SWC, and next/babel is obsolete. If you’re still using Babel (e.g., for custom plugins), you can migrate to SWC by:
- Deleting
.babelrc,babel.config.js, and@babel/*dependencies. - Adding
next.config.js:js// next.config.js module.exports = { compiler: { // Remove this if you need Babel features // styledComponents: true, } }; - Updating ESLint to use
@typescript-eslint/parser(as above).
SWC is 7x faster than Babel and eliminates the next/babel resolution issue entirely — because it doesn’t use Babel presets at all. I explain this in depth in Next.js App Router Guide: From Basics to Advanced Patterns, where we benchmark SWC vs Babel in real-world projects.
FAQ#
Do I need to install @babel/core to fix this error?#
No — Next.js bundles @babel/core internally. Installing it manually often causes version conflicts (e.g., @babel/core@7.20.0 vs Next.js’s 7.22.0). The fix is purely configuration: update ESLint to use @typescript-eslint/parser, not babel-eslint.
Will switching to SWC remove the need for next/babel?#
Yes — SWC is Next.js’s native compiler and doesn’t use Babel presets. If you’re on Next.js 13+, you’re already using SWC unless you explicitly opt into Babel via next.config.js. No next/babel configuration is needed.
Why is this error only showing up in VS Code and not during the build?#
VS Code’s ESLint extension runs in a separate process and uses its own resolution rules. next build uses Next.js’s internal compiler, which resolves next/babel at runtime — not via Node.js require(). That’s why your app compiles fine while ESLint fails.
How do I disable the specific ESLint rule if using a custom compiler?#
If you must use a custom Babel setup (e.g., for styled-components), add to .eslintrc.json:
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": ["./tsconfig.json"],
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/no-unused-vars": "off"
}
}
But again — prefer SWC unless you need Babel-specific features.
Related#
- Next.js Hydration Mismatch Error: Production Fix Guide
- AI Integration for Next.js + Supabase Applications
- Deploying Next.js + Supabase to Production
- How to Structure Your Next.js App Router Project for Scale
- Next.js & Supabase Masterclass: Robust CI/CD Pipelines with GitHub Actions
Dealing with ESLint configuration mismatches is a rite of passage for any Next.js developer, but once you align your tooling with SWC, your development environment becomes significantly more robust.
Related fixes & guides
- Fix useEffect Running Twice in React 18 — Strict Mode
- Complete Type Safety Guide for Next.js and Supabase with TypeScript
- Interfaces vs Types in TypeScript: 2026 Best Practices
- Error Handling and Observability for Next.js and Supabase Applications
- How to Access Route Parameter Inside getServerSideProps
- TypeScript Migration Guide 2026: Upgrade JavaScript Projects Safely
- Fix Next.js Module Not Found After Deploy or Production Build
- Fix port setting in Next.js