Guia de Migração ESLint 10: Tudo sobre a maior atualização
ESLint 10 acabou de sair, e não é uma atualização menor. O sistema de config .eslintrc que você tava se agarrando? Removido completamente—não deprecado, removido. A flag --env? Foi embora. Node.js 18? Não suporta mais.
Essa é a declaração do time do ESLint: flat config é o único caminho.
Se você vinha adiando a migração, janeiro 2026 é seu deadline. ESLint 9 tá em modo de manutenção. ESLint 10 é o presente. Esse guia vai te levar sem quebrar seu pipeline de CI.
O que tem de novo no ESLint 10
Vamos ver o que mudou antes de mergulhar na migração.
Node.js 20.19.0+ obrigatório
ESLint 10 para de suportar Node.js 18, 19, 21 e 23. Você precisa de:
- Node.js ^20.19.0 (20.19.0 ou superior no 20.x)
- Node.js ^22.13.0 (22.13.0 ou superior no 22.x LTS)
- Node.js >=24.0.0 (24.x Current)
Confere seus pipelines de CI/CD. Isso vai quebrar builds em versões antigas do Node imediatamente.
node --version # Tem que ser v20.19.0+
Remoção completa do .eslintrc
Essa é a grande. ESLint 10 remove tudo relacionado à configuração legacy:
| Removido | Substituto |
|---|---|
Arquivos .eslintrc.* | eslint.config.js |
.eslintignore | Array ignores na config |
Flag --env | globals em languageOptions |
Flag --rulesdir | Imports diretos de plugins |
--resolve-plugins-relative-to | Imports de módulos ES |
Comentários /* eslint-env */ | Agora reportados como erros |
Variável env ESLINT_USE_FLAT_CONFIG | Sempre flat config |
API LegacyESLint | Totalmente removida |
Se seu projeto ainda usa .eslintrc.json, ESLint 10 simplesmente ignora.
Novo lookup de arquivos de config
ESLint 10 muda como encontra arquivos de config:
ESLint 9 (comportamento antigo):
Busca do CWD pra cima por eslint.config.js
ESLint 10 (comportamento novo):
Busca do diretório de cada arquivo lintado pra cima por eslint.config.js
Isso é enorme pra monorepos. Cada pacote pode ter seu próprio eslint.config.js, e o ESLint encontra automaticamente.
my-monorepo/
├── eslint.config.js # Config raiz (fallback)
├── packages/
│ ├── web/
│ │ ├── eslint.config.js # Config específica web
│ │ └── src/
│ └── api/
│ ├── eslint.config.js # Config específica API
│ └── src/
Tracking de referências JSX
ESLint 10 agora rastreia referências de elementos JSX pra análise de escopo precisa:
- Componentes custom são trackeados apropriadamente como referências
no-unused-varsfunciona corretamente com JSX- Código existente pode disparar novos warnings (false positives na v9)
// ESLint 10 agora vê Button corretamente como referência import { Button } from './components'; function App() { return <Button>Click me</Button>; // Button é trackeado }
eslint:recommended atualizado
O ruleset recomendado foi atualizado. Roda ESLint depois de migrar pra pegar novas violações.
Migração passo a passo do ESLint 9
Passo 1: Confere versão do Node.js
node --version # Se for menor que v20.19.0, atualiza primeiro
Atualiza seu CI/CD pra usar Node.js 20.x LTS ou 22.x.
Passo 2: Atualiza ESLint e dependências
npm install eslint@10 --save-dev # Atualiza TypeScript ESLint se usa TypeScript npm install @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest --save-dev # Atualiza outros plugins npm install eslint-plugin-react@latest eslint-plugin-react-hooks@latest --save-dev
Passo 3: Migra a config (se ainda não fez)
Se ainda tá no .eslintrc, usa a ferramenta de migração:
npx @eslint/migrate-config .eslintrc.json
Isso gera um arquivo eslint.config.mjs. Revisa e ajusta.
Passo 4: Atualiza tua Flat Config pra compatibilidade v10
Se já tem eslint.config.js, confere essas atualizações específicas da v10:
Remove comentários eslint-env
// ❌ ESLint 10 reporta isso como erro /* eslint-env browser, node */ // ✅ Usa globals na config import globals from "globals"; export default [ { languageOptions: { globals: { ...globals.browser, ...globals.node, } } } ];
Passo 5: Deleta arquivos legacy
rm .eslintrc.* .eslintignore 2>/dev/null || true
Passo 6: Atualiza config do VS Code
{ "eslint.useFlatConfig": true }
Nota: A config eslint.useFlatConfig agora é o default. Pode remover.
Passo 7: Testa
npx eslint .
Corrige novas violações do eslint:recommended atualizado ou mudanças no tracking JSX.
Exemplos completos de config ESLint 10
Projeto TypeScript
// eslint.config.js import js from "@eslint/js"; import typescript from "typescript-eslint"; import globals from "globals"; export default typescript.config( js.configs.recommended, ...typescript.configs.recommendedTypeChecked, { languageOptions: { globals: globals.node, parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname, }, }, }, { files: ["**/*.js", "**/*.mjs"], ...typescript.configs.disableTypeChecked, }, { ignores: ["dist/**", "node_modules/**"], } );
React + TypeScript (Next.js)
// eslint.config.mjs import js from "@eslint/js"; import typescript from "typescript-eslint"; import react from "eslint-plugin-react"; import reactHooks from "eslint-plugin-react-hooks"; import jsxA11y from "eslint-plugin-jsx-a11y"; import next from "@next/eslint-plugin-next"; import globals from "globals"; export default typescript.config( js.configs.recommended, ...typescript.configs.recommended, // React + JSX { files: ["**/*.{jsx,tsx}"], plugins: { react, "react-hooks": reactHooks, "jsx-a11y": jsxA11y, }, languageOptions: { globals: globals.browser, parserOptions: { ecmaFeatures: { jsx: true }, }, }, settings: { react: { version: "detect" }, }, rules: { ...react.configs.recommended.rules, ...react.configs["jsx-runtime"].rules, ...reactHooks.configs.recommended.rules, ...jsxA11y.configs.recommended.rules, }, }, // Next.js { plugins: { "@next/next": next, }, rules: { ...next.configs.recommended.rules, ...next.configs["core-web-vitals"].rules, }, }, { ignores: [".next/**", "node_modules/**", "out/**"], } );
Monorepo com configs por pacote
// Raiz: eslint.config.js import js from "@eslint/js"; import typescript from "typescript-eslint"; // Config base que todos os pacotes herdam export default typescript.config( js.configs.recommended, ...typescript.configs.recommended, { ignores: ["**/dist/**", "**/node_modules/**"], } );
// packages/web/eslint.config.js import baseConfig from "../../eslint.config.js"; import react from "eslint-plugin-react"; import globals from "globals"; export default [ ...baseConfig, { files: ["**/*.{jsx,tsx}"], plugins: { react }, languageOptions: { globals: globals.browser, }, rules: { ...react.configs.recommended.rules, }, }, ];
O novo algoritmo de lookup do ESLint 10 vai usar automaticamente o eslint.config.js mais próximo de cada arquivo.
Erros comuns de migração e soluções
Error: "ESLint requires Node.js version ^20.19.0 || ^22.0.0 || >=24.0.0"
Solução: Atualiza Node.js pra 20.19.0 ou superior.
# Usando nvm nvm install 22 nvm use 22
Error: "eslint-env is no longer supported"
Solução: Remove comentários /* eslint-env */ e usa globals:
import globals from "globals"; { languageOptions: { globals: globals.browser } }
Error: "ConfigArray.normalize is not a function"
Solução: Atualiza @eslint/eslintrc pra última versão:
npm install @eslint/eslintrc@latest
Error: "Cannot find config" em monorepo
Solução: ESLint 10 busca do diretório do arquivo, não do CWD. Opções:
- Adiciona
eslint.config.jsem cada pacote, ou - Roda ESLint da raiz com patterns de arquivo explícitos
Warning: Novas violações do tracking JSX
Solução: Provavelmente são problemas reais que a v9 não pegou. Revisa cada um. Se for false positive, desabilita a regra pra aquela linha.
Checklist de migração
Usa esse checklist pra sua migração:
- Node.js é v20.19.0+ ou v22.x
- ESLint atualizado pra v10
- Todos os plugins atualizados pra versões compatíveis com v10
- Config migrada pra
eslint.config.js - Todos os comentários
/* eslint-env */removidos - Arquivos
.eslintrc.*deletados -
.eslintignoredeletado (usaignoresna config) - CI/CD atualizado pra Node.js 20+
- Config do VS Code atualizada
- Lint completo passa
Devo migrar agora?
Sim. Razões:
- ESLint 9 tá em modo de manutenção—sem features novas, só fixes críticos
- Ecossistema de plugins tá se movendo—plugins populares tão parando de suportar v9
- O novo algoritmo de lookup é poderoso—especialmente pra monorepos
- Tracking JSX encontra bugs reais—seu código existente pode ter problemas que você não sabia
A migração é bem mecânica. Se você já migrou pra flat config na v9, tá 90% pronto. Se ainda tá no .eslintrc, agora é a hora—não tem mais tempo.
Conclusão
ESLint 10 é uma quebra limpa com o passado. O sistema de config legacy foi embora de vez. O que você ganha em troca:
- Modelo mental mais simples: Um arquivo, um formato, sem mágica
- Melhor suporte monorepo: Configs por pacote que só funcionam
- Linting mais preciso: Tracking JSX encontra problemas reais
- Preparado pro futuro: Você tá no caminho que o ecossistema tá tomando
A migração pode levar uma hora ou duas, mas você vai estar preparado pros próximos anos de releases do ESLint.
Uma dívida técnica a menos. Agora vai lá atualizar essas configs! 🚀
Explore ferramentas relacionadas
Experimente estas ferramentas gratuitas do Pockit