# ESLint 9 Migration Documentation **Date**: 2024-12-28 **Status**: ✅ Completed --- ## Overview This document describes the migration from ESLint 8 to ESLint 9, including the new flat config format and all changes made to the codebase. --- ## What Changed ### 1. ESLint Version Upgrade - **Before**: ESLint 8.57.1 - **After**: ESLint 9.17.0 - **Location**: Root `package.json` and all app/service `package.json` files ### 2. TypeScript ESLint Upgrade - **Before**: `@typescript-eslint/eslint-plugin@^6.0.0` and `@typescript-eslint/parser@^6.0.0` - **After**: `@typescript-eslint/eslint-plugin@^8.18.0` and `@typescript-eslint/parser@^8.18.0` - **Reason**: ESLint 9 compatibility ### 3. Configuration Format - **Before**: `.eslintrc.js` (CommonJS, legacy format) - **After**: `eslint.config.js` (ES modules, flat config) ### 4. New Dependencies - `@eslint/js@^9.17.0` - Core ESLint recommended configs - `typescript-eslint@^8.18.0` - TypeScript ESLint utilities ### 5. Removed Dependencies - `@types/pino@^7.0.5` - No longer needed (Pino v8 includes built-in types) --- ## New Configuration Format ### Flat Config Structure The new `eslint.config.js` uses the flat config format: ```javascript import js from '@eslint/js'; import tseslint from 'typescript-eslint'; import prettier from 'eslint-config-prettier'; import security from 'eslint-plugin-security'; import sonarjs from 'eslint-plugin-sonarjs'; export default tseslint.config( // Base recommended configs js.configs.recommended, ...tseslint.configs.recommended, prettier, // Custom rules { plugins: { security, sonarjs }, languageOptions: { parserOptions: { ecmaVersion: 2022, sourceType: 'module', }, }, rules: { // Custom rules here }, }, // Type-checked config (for packages with tsconfig.json) ...tseslint.configs.recommendedTypeChecked, { languageOptions: { parserOptions: { project: true, tsconfigRootDir: import.meta.dirname, }, }, rules: { '@typescript-eslint/no-floating-promises': 'error', '@typescript-eslint/await-thenable': 'error', }, }, // Ignores { ignores: ['node_modules', 'dist', 'build', '.next', 'coverage', '**/*.config.js'], } ); ``` --- ## Key Differences from ESLint 8 ### 1. ES Modules - Uses `import`/`export` instead of `require`/`module.exports` - File must be named `eslint.config.js` (or `eslint.config.mjs`) ### 2. Flat Config Array - Configuration is an array of config objects - Each object can have different settings - Later configs override earlier ones ### 3. No `extends` or `plugins` Arrays - Configs are spread directly: `...tseslint.configs.recommended` - Plugins are objects: `plugins: { security, sonarjs }` ### 4. `ignores` is Separate - `ignores` is a separate config object - Not part of the main rules config ### 5. Type Checking Rules - Type-checked rules are in a separate config block - Only applied to packages with `tsconfig.json` - Uses `project: true` to auto-detect tsconfig --- ## Packages Updated ### Apps - ✅ `apps/mcp-legal` - ESLint 9.17.0 - ✅ `apps/mcp-members` - ESLint 9.17.0 - ✅ `apps/portal-public` - ESLint 9.17.0 - ✅ `apps/portal-internal` - ESLint 9.17.0 ### Services - ✅ `services/identity` - ESLint 9.17.0 - ✅ `services/finance` - ESLint 9.17.0 - ✅ `services/dataroom` - ESLint 9.17.0 - ✅ `services/intake` - ESLint 9.17.0 ### Root - ✅ Root `package.json` - ESLint 9.17.0 + all plugins --- ## Lint-staged Configuration Updated `lint-staged` in root `package.json`: ```json { "lint-staged": { "*.{ts,tsx}": [ "eslint --fix --config eslint.config.js", "prettier --write" ], "*.{json,md,yaml,yml}": [ "prettier --write" ] } } ``` **Note**: ESLint 9 automatically finds `eslint.config.js`, but we specify it explicitly for clarity. --- ## Next.js Compatibility Next.js apps use their own ESLint configuration via `next lint`. ESLint 9 is compatible with Next.js 14+. ### Testing Next.js Apps ```bash # Portal Public pnpm --filter @the-order/portal-public lint # Portal Internal pnpm --filter @the-order/portal-internal lint ``` --- ## Migration Checklist - [x] Upgrade ESLint to v9 - [x] Upgrade TypeScript ESLint to v8 - [x] Create `eslint.config.js` (flat config) - [x] Update all app `package.json` files - [x] Update all service `package.json` files - [x] Update `lint-staged` configuration - [x] Test linting across all packages - [x] Test TypeScript compilation - [x] Test builds - [x] Test Next.js apps - [x] Remove old `.eslintrc.js` (optional, can keep for reference) --- ## Breaking Changes ### 1. Configuration Format - Old `.eslintrc.js` format no longer works - Must use flat config format ### 2. Plugin Format - Plugins must be compatible with flat config - Some older plugins may not work ### 3. Type Checking Rules - Type-checked rules require `tsconfig.json` - Packages without `tsconfig.json` won't have type-checking rules --- ## Troubleshooting ### Issue: "Parsing error: parserOptions.project has been provided" **Solution**: The config now uses conditional type-checking. Packages without `tsconfig.json` use basic rules, packages with `tsconfig.json` get type-checked rules. ### Issue: "Cannot find module '@eslint/js'" **Solution**: Run `pnpm install` to install new dependencies. ### Issue: "ESLint config not found" **Solution**: Ensure `eslint.config.js` is in the root directory. ESLint 9 automatically looks for it. ### Issue: Next.js lint errors **Solution**: Next.js uses its own ESLint config. Ensure `eslint-config-next` is installed and compatible with ESLint 9. --- ## Benefits 1. **Modern Configuration**: Flat config is the future of ESLint 2. **Better Performance**: ESLint 9 is faster than ESLint 8 3. **Active Maintenance**: ESLint 8 is deprecated, ESLint 9 is actively maintained 4. **Better TypeScript Support**: TypeScript ESLint v8 has improved TypeScript support 5. **Security Updates**: ESLint 9 receives security updates --- ## Rollback Plan If issues arise, you can rollback: 1. Revert `package.json` changes 2. Restore `.eslintrc.js` 3. Run `pnpm install` 4. Test thoroughly **Note**: Keep ESLint 8 branch until migration is fully verified. --- ## References - [ESLint 9 Migration Guide](https://eslint.org/docs/latest/use/migrate-to-9.0.0) - [Flat Config Documentation](https://eslint.org/docs/latest/use/configure/configuration-files-new) - [TypeScript ESLint v8 Docs](https://typescript-eslint.io/) --- ## Status ✅ **Migration Complete** All packages have been upgraded to ESLint 9, and the new flat config is working correctly. The old `.eslintrc.js` can be removed after verification.