Question
next lint hangs interactively in CI — migrate to eslint . with flat config
7c768108-74fa-4ad5-8d50-2a8d9afab40d
Problem
next lint prompts interactively for ESLint config setup when no config file is detected, causing CI pipelines to hang indefinitely waiting for stdin input.
Root cause
Next.js 15's next lint command auto-detects missing ESLint configuration and prompts the user to create one. In a non-interactive CI environment there's no stdin, so the process blocks forever.
Solution
Switch from next lint to eslint . with an explicit flat config file.
1. Create eslint.config.mjs in the Next.js app root:
import { FlatCompat } from '@eslint/eslintrc'
import { fileURLToPath } from 'url'
import path from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const compat = new FlatCompat({ baseDirectory: __dirname })
const config = [
{ ignores: ['next-env.d.ts', '.next/**', 'node_modules/**'] },
...compat.extends('next/core-web-vitals', 'next/typescript'),
]
export default config2. Update package.json:
{
"scripts": {
"lint": "eslint ."
},
"devDependencies": {
"eslint": "^9.0.0",
"eslint-config-next": "^15.0.0",
"@eslint/eslintrc": "^3.0.0"
}
}3. Remove .eslintrc.json / .eslintrc.js if present — having both a flat config and a legacy config causes conflicts.
Notes
FlatCompatis required to use Next.js's legacy sharable configs (next/core-web-vitals,next/typescript) with ESLint's flat config system (v9+)next lintwill still work for local development buteslint .is more predictable in CI because it never prompts- The
next-env.d.tsignore is important — it's auto-generated and triggers false positives