Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Manual memoization is therefore:

The codebase enforces this via:
- **Babel plugin**: `babel-plugin-react-compiler` in `babel.config.js`
- **ESLint processor**: `eslint-processor-react-compiler-compat` suppresses redundant lint rules when files compile successfully
- **Lint post-processor**: `scripts/lint/processors/ReactCompilerFilter.ts` suppresses redundant lint rules when both React Compilers memoize the file
- **CI compliance check**: `scripts/react-compiler-compliance-check.ts` enforces that new components/hooks compile and that existing compiled files don't regress

Reference: [React Compiler documentation](https://react.dev/learn/react-compiler)
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ on:
'config/.editorconfig',
'config/eslint/**',
'scripts/lint.ts',
'scripts/lint/**',
'scripts/lintChanged.sh',
'.watchmanconfig',
'.imgbotconfig',
Expand Down
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Do not use `useMemo`, `useCallback`, or `React.memo` in components or hooks that

### Code Quality

- **ESLint**: Linter. Pre-existing violations are grandfathered via [`eslint-seatbelt`](https://github.com/justjake/eslint-seatbelt).
- **ESLint**: Linter. Pre-existing violations are grandfathered via the seatbelt ratchet in `scripts/lint/`.

### Post-Edit Checklist (IMPORTANT)

Expand Down
32 changes: 4 additions & 28 deletions config/eslint/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import reactNativeA11Y from 'eslint-plugin-react-native-a11y';
import rulesdir from 'eslint-plugin-rulesdir';
import testingLibrary from 'eslint-plugin-testing-library';
import youDontNeedLodashUnderscore from 'eslint-plugin-you-dont-need-lodash-underscore';
import seatbelt from 'eslint-seatbelt';
import {defineConfig, globalIgnores} from 'eslint/config';
import globals from 'globals';
import {createRequire} from 'node:module';
Expand All @@ -22,7 +21,6 @@ import {fileURLToPath} from 'node:url';
import tseslint from 'typescript-eslint';

import reportNameUtilsPlugin from './plugins/eslint-plugin-report-name-utils.mjs';
import expensifyProcessor from './processors/eslint-processor-expensify.mjs';

const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);
Expand Down Expand Up @@ -199,7 +197,7 @@ const restrictedReportNameImportPatterns = [
];

// `isPaidGroupPolicy` is BILLING/paid-only (Collect/Control). Existing usages are grandfathered via
// eslint-seatbelt; this only flags NEW imports so they make a conscious choice: for workspace feature
// the seatbelt baseline; this only flags NEW imports so they make a conscious choice: for workspace feature
// gating (violations, report fields, workspace chat, report creation, expense-workspace usability) use
// `isGroupPolicy` / `isReportInGroupPolicy` instead, otherwise free group plans like Submit (submit2026)
// are wrongly excluded and access bugs return.
Expand Down Expand Up @@ -240,35 +238,13 @@ const config = defineConfig([
},
},
},
fileProgress.configs['recommended-ci'],

// Suppress lint rules that are unnecessary for files successfully compiled by React Compiler.
// The processor runs React Compiler on each file and filters out redundant lint messages.
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs'],
processor: expensifyProcessor,
},

// eslint-seatbelt config. The processor is stitched into `expensifyProcessor`
// above, so we only wire up the plugin, settings, and `configure` rule here.
{
...fileProgress.configs['recommended-ci'],
settings: {
seatbelt: {
seatbeltFile: path.join(dirname, 'eslint.seatbelt.tsv'),
threadsafe: true,
// Never persist TSV updates unless we're in CI. In CI, the ephemeral
// write is harmless on PR runs and essential on `push: main`, where
// OSBotify commits the tightened baseline back to main
// (see .github/workflows/lint.yml). SEATBELT_INCREASE overrides this.
readOnly: !process.env.CI,
progress: {
hide: process.env.CI === 'true' || process.env.LINT_PIPELINE === '1',
},
},
plugins: {
'eslint-seatbelt': seatbelt,
},
rules: {
'eslint-seatbelt/configure': 'error',
},
},

{
Expand Down
27 changes: 0 additions & 27 deletions config/eslint/processors/eslint-processor-expensify.mjs

This file was deleted.

This file was deleted.

152 changes: 0 additions & 152 deletions config/eslint/processors/eslint-processor-stratify-no-deprecated.mjs

This file was deleted.

Loading
Loading